I come from OOP background and trying to learn python.
I am using the max
function which uses a lambda expression to return the instance of type Player
having maximum totalScore
among the list players
.
def winner():
w = max(players, key=lambda p: p.totalScore)
The function correctly returns instance of type Player
having maximum totalScore
.
I am confused about the following three things:
- How does the
max
function work? What are the arguments it is taking? I looked at the documentation but failed to understand. - What is use of the keyword
key
in max function? I know it is also used in context ofsort
function - Meaning of the lambda expression? How to read them? How do they work?
These are all very noobish conceptual questions but will help me understand the language. It would help if you could give examples to explain. Thanks
max
function is used to get the maximum out of aniterable
.The iterators may be lists, tuples, dict objects, etc. Or even custom objects as in the example you provided.
So, the
key=func
basically allows us to pass an optional argumentkey
to the function on whose basis the the given iterator/arguments are sorted & the maximum is returned.lambda
is a python keyword that acts as a pseudo function. So, when you passplayer
object to it, it will returnplayer.totalScore
. Thus, the iterable passed over to functionmax
will sort according to thekey
totalScore of theplayer
objects given to it & will return theplayer
who has maximumtotalScore
.If no
key
argument is provided, the maximum is returned according to default Python orderings.Examples -
lambda
is an anonymous function, it is equivalent to:Now
max
becomes:But as
def
statements are compound statements they can't be used where an expression is required, that's why sometimeslambda
'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 alambda
, only expressions are allowed.What does max do?
So, it simply returns the object that is largest.
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've a list of numbers in string form, but you want to compare those items by their integer value.
Here
max
compares the items using their original values(strings are compared lexicographically so you'd get'2'
as output) :To compare the items by their integer value use key with a simple
lambda
:Example 2: Applying
max
to a list of lists.By default max will will compare the items by the first index, if the first index is same then it'd compare the second index. As in my example all items have unique first index so, you'd get this as the answer:
But, what if you wanted to compare each item by the value at index 1? Simple, use
lambda
:Comparing items in an iterable that contains objects of different type:
List with mixed items:
In Python 2 it is possible to compare items of two different types:
But in Python 3 you can't do that any more:
But this works, as we are comparing integer version of each object:
Strongly simplified version of
max
:Regarding lambda:
max
is built in function which takes first argument aniterable
(like list or tuple)keyword argument
key
has it's default valueNone
but it accept function to evaluate, consider it as wrapper which evaluates iterable based on functionConsider this example dictionary:
Ex:
As you can see if you only pass the iterable without kwarg(a function to
key
) it is returning maximum value of key(alphabetically)Ex. Instead of finding max value of key alphabetically you might need to find max key by length of key:
in this example lambda function is returning length of key which will be iterated hence while evaluating values instead of considering alphabetically it will keep track of max length of key and returns key which has max length
Ex.
in this example lambda function is returning value of corresponding dictionary key which has maximum value
According to the documentation:
What this is saying is that in your case, you are providing a list, in this case
players
. Then themax
function will iterate over all the items in the list and compare them to each other to get a "maximum".As you can imagine, with a complex object like a
player
determining its value for comparison is tricky, so you are given thekey
argument to determine how themax
function will decide the value of eachplayer
. In this case, you are using a lambda function to say "for eachp
inplayers
getp.totalscore
and use that as his value for comparison".It looks for the "largest" item in an iterable. I'll assume that you can look up what that is, but if not, it's something you can loop over, i.e. a list or string.
Key
is a lambda function that will tellmax
which objects in the iterable are larger than others. Say if you were sorting some object that you created yourself, and not something obvious, like integers.That's sort of a larger question. In simple terms, a lambda is a function you can pass around, and have other pieces of code use it. Take this for example:
This takes two objects,
a
andb
, and a functionf
. It callsf()
on each object, then adds them together. So look at this call:sum()
takes2
, and calls the lambda expression on it. Sof(a)
becomes2 * 2
, which becomes 4. It then does this forb
, and adds the two together.In not so simple terms, lambdas come from lambda calculus, which is the idea of a function that returns a function; a very cool math concept for expressing computation. You can read about that here, and then actually understand it here.
It's probably better to read about this a little more, as lambdas can be confusing, and it's not immediately obvious how useful they are. Check here.