lambda is an anonymous function, it is equivalent to:
def func(p):
return p.totalScore
Now max becomes:
max(players, key=func)
But as def statements are compound statements they can't be used where an expression is required, that's why sometimes lambda's are used.
Note that lambda is equivalent to what you'd put in a return statement of a def. Thus, you can't use statements inside a lambda, only expressions are allowed.
What does max do?
max(a, b, c, ...[, key=func]) -> value
With a single iterable argument, return its largest item. With two or more arguments, return the largest argument.
So, it simply returns the object that is the largest.
How does key work?
By default in Python 2 key compares items based on a set of rules based on the type of the objects (for example a string is always greater than an integer).
To modify the object before comparison, or to compare based on a particular attribute/index, you've to use the key argument.
Example 1:
A simple example, suppose you have a list of numbers in string form, but you want to compare those items by their integer value.
>>> lis = ['1', '100', '111', '2']
Here max compares the items using their original values (strings are compared lexicographically so you'd get '2' as output) :
>>> max(lis)
'2'
To compare the items by their integer value use key with a simple lambda:
>>> max(lis, key=lambda x:int(x)) # compare `int` version of each item
'111'
Example 2: Applying max to a list of tuples.
>>> lis = [(1,'a'), (3,'c'), (4,'e'), (-1,'z')]
By default max will compare the items by the first index. If the first index is the same then it'll compare the second index. As in my example, all items have a unique first index, so you'd get this as the answer:
>>> max(lis)
(4, 'e')
But, what if you wanted to compare each item by the value at index 1? Simple: use lambda:
>>> max(lis, key = lambda x: x[1])
(-1, 'z')
Comparing items in an iterable that contains objects of different type:
List with mixed items:
lis = ['1','100','111','2', 2, 2.57]
In Python 2 it is possible to compare items of two different types:
>>> max(lis) # works in Python 2
'2'
>>> max(lis, key=lambda x: int(x)) # compare integer version of each item
'111'
But in Python 3 you can't do that any more:
>>> lis = ['1', '100', '111', '2', 2, 2.57]
>>> max(lis)
Traceback (most recent call last):
File "<ipython-input-2-0ce0a02693e4>", line 1, in <module>
max(lis)
TypeError: unorderable types: int() > str()
But this works, as we are comparing integer version of each object:
>>> max(lis, key=lambda x: int(x)) # or simply `max(lis, key=int)`
'111'
Answer from Ashwini Chaudhary on Stack Overflowlambda is an anonymous function, it is equivalent to:
def func(p):
return p.totalScore
Now max becomes:
max(players, key=func)
But as def statements are compound statements they can't be used where an expression is required, that's why sometimes lambda's are used.
Note that lambda is equivalent to what you'd put in a return statement of a def. Thus, you can't use statements inside a lambda, only expressions are allowed.
What does max do?
max(a, b, c, ...[, key=func]) -> value
With a single iterable argument, return its largest item. With two or more arguments, return the largest argument.
So, it simply returns the object that is the largest.
How does key work?
By default in Python 2 key compares items based on a set of rules based on the type of the objects (for example a string is always greater than an integer).
To modify the object before comparison, or to compare based on a particular attribute/index, you've to use the key argument.
Example 1:
A simple example, suppose you have a list of numbers in string form, but you want to compare those items by their integer value.
>>> lis = ['1', '100', '111', '2']
Here max compares the items using their original values (strings are compared lexicographically so you'd get '2' as output) :
>>> max(lis)
'2'
To compare the items by their integer value use key with a simple lambda:
>>> max(lis, key=lambda x:int(x)) # compare `int` version of each item
'111'
Example 2: Applying max to a list of tuples.
>>> lis = [(1,'a'), (3,'c'), (4,'e'), (-1,'z')]
By default max will compare the items by the first index. If the first index is the same then it'll compare the second index. As in my example, all items have a unique first index, so you'd get this as the answer:
>>> max(lis)
(4, 'e')
But, what if you wanted to compare each item by the value at index 1? Simple: use lambda:
>>> max(lis, key = lambda x: x[1])
(-1, 'z')
Comparing items in an iterable that contains objects of different type:
List with mixed items:
lis = ['1','100','111','2', 2, 2.57]
In Python 2 it is possible to compare items of two different types:
>>> max(lis) # works in Python 2
'2'
>>> max(lis, key=lambda x: int(x)) # compare integer version of each item
'111'
But in Python 3 you can't do that any more:
>>> lis = ['1', '100', '111', '2', 2, 2.57]
>>> max(lis)
Traceback (most recent call last):
File "<ipython-input-2-0ce0a02693e4>", line 1, in <module>
max(lis)
TypeError: unorderable types: int() > str()
But this works, as we are comparing integer version of each object:
>>> max(lis, key=lambda x: int(x)) # or simply `max(lis, key=int)`
'111'
Strongly simplified version of max:
def max(items, key=lambda x: x):
current = item[0]
for item in items:
if key(item) > key(current):
current = item
return current
Regarding lambda:
>>> ident = lambda x: x
>>> ident(3)
3
>>> ident(5)
5
>>> times_two = lambda x: 2*x
>>> times_two(2)
4
Use a lambda function to find the maximum of a list in python - Stack Overflow
Can anyone help me with understanding lambda? I have added a sample question with my code not involving lambda and another code involving it
python - How to get the min/max in a list by using a lambda or function to get a comparison value from the item? - Stack Overflow
[Python] Question! I am having trouble with min/max
I was practicing coding and I saw some very interesting solutions involving lambda. For example-
The question is-
Given a string of words, you need to find the highest scoring word.
Each letter of a word scores points according to its position in the alphabet:
a = 1, b = 2, c = 3etc.
For example, the score of
abadis8(1 + 2 + 1 + 4).
You need to return the highest scoring word as a string.
If two words score the same, return the word that appears earliest in the original string.
All letters will be lowercase and all inputs will be valid.
My code-
def high(x):
dict1 = {'a':1,'b':2,'c':3,'d':4,'e':5,'f':6,'g':7,'h':8,'i':9,'j':10,'k':11,'l':12,'m':13,'n':14,'o':15,'p':16,'q':17,'r':18,'s':19,'t':20,'u':21,'v':22,'w':23,'x':24,'y':25,'z':26}
split = x.split()
sum= [0 for i in range(len(split))]
#split1 = split[0].split("")
for i in range(len(split)):
for j in split[i]:
sum[i]+= dict1[j]
i = sum.index(max(sum))
return split[i] Meanwhile someone else's code who did it using lambda-
def high(x):
return max(x.split(), key=lambda k: sum(ord(c) - 96 for c in k))I am finding lambda a bit confusing but seems it has potential to shorten my code by a lot
If you don't need the index, you can use the result directly:
value = max(items, key=lambda(item) : item.cost * item.quantity)
print value.cost, value.quantity
max returns the actual max item, which is a Mock instance. You can't unpack it into two items.
If you really want the index, you can either find it, or modify your search a little bit to decorate the index into the item:
index, value = max(enumerate(items), key=lambda(item): item[1].cost * item[1].quantity)
First, we convert the original list into a second list where each item is a tuple of (index, value). Then, the key also has to change, because instead of item.cost, item is now an (index, MockItem) pair, and so you need to get item[1], then get the attributes. Don't forget to unpack the result into index and value to get both.
This is not the most efficient way but it's easy for anyone reading it to understand. If you have very large lists, let me know and I'll point you to more efficient solutions.
# get the value
max_item = max(items, key=lambda item: item.cost * item.quantity)
# get the index
max_item_index = items.index(max_item)
If you also want the calculated value, then just do a loop to keep it clear:
max_value = max_index = max_item = None
for i, item in enumerate(items):
value = item.cost * item.quantity
if (max_value is None) or (value > max_value):
max_value = value
max_index = i
max_item = item
if max_value is not None:
print max_index, max_value, max_item