Dnaiel
Dnaiel

Reputation: 7832

Difficulty understanding lambda function in sort

Let's say I define a list of lists lol:

lol = [['malasia', 0.02, 56.3], ['chile', 0.03, 34.9],
       ['hungria', 0.01, 45.9], ['ahumada', 0.001, 1]]

Then,

lol.sort(lambda x, y: cmp(y[2], x[2]))

orders lol by the last element of each sublist...


I'm just trying to understand the component parts of the sort:

Upvotes: 4

Views: 6942

Answers (4)

Don Question
Don Question

Reputation: 11614

The lambda function in your example determines which item comes first.

In a "classical"-situation it would simply calculate x-y: if the result is negative it means that x is smaller then y and therefore comes before y.

Additionally you may pass a reverse-parameter to the sort-method, which would reverse=True the order.

Your "sort"-function is in this case the cmp-function in the "lambda-wrapper". Therein you swap the order of x with y and use the 3rd argument, which means it sorts in a reversed order(x/y-swap) and does it by comparing all the 3rd arguments(x[2]).

Regarding your 2nd bullet:

... could anybody explain what the lambda function does"

If your asking what a lambda-function is: It's an anonymous light-weight inline function. Anonymous means it doesn't have an identifier. (But you could assign one. e.g.: sqr = lambda x : x**2 which you could use now like any other function: y = sqr(2))

Normal function: def name(arg): vs lambda-function: lambda   arg: ret_value
                  ^    ^    ^                          ^   ^  ^       ^
                  a)   b)   c)                         a)  b) c)      d)
  • a) keyword marking the following as a normal/lambda-function
  • b) function-name in case of the lambda functio "missing" therefore anonymous
  • c) function arguments: normal function ->brackets, lambda-function -> without
  • d) return value - in case of the normal function omitted, because must be explicitly returned with return. (without explicit return it delivers None) The lambda implicitly returns the result of the evaluation on the right side of the colon.

Your example of the sort-function use is a typical use-case for lambda-functions. They are used as "throw-away" functions, which you may inline without to create a own normal function.

A more "pythonic" variation would be something like:

from operator import itemgetter

keyfunc = itemgetter(2) # takes the 3rd argument from an itterable
sorted_list = sorted(lol, key=keyfunc, reverse=True)

Upvotes: 3

octref
octref

Reputation: 6801

lambda is of type "function"
So your

lambda x, y : cmp(y[2], x[2])

is equal to

def f(x, y):
    return cmp(y[2], x[2])

The sort takes a function, and when it need to compare two elements, it would call that lambda function, which would return the value of cmp(y[2], x[2])

So this sort would sort your list in this way: whenever it meets two element, it would fetch the last values in the "triples" and compare them to determine the precedence.

Upvotes: 1

jleahy
jleahy

Reputation: 16855

This is actually better done using the key argument to sort, cmp is somewhat outdated.

For example:

lol.sort(key=lambda x: x[2])

(you could also use x[-1] to mean the last element of the list)

You are creating the lambda and passing it into the sort function. You could also write it like this:

get_third_element = lambda x: x[2]
lol.sort(key=get_third_element)

Or to make it even easier to understand:

def get_third_element(x):
    return x[2]

lol.sort(key=get_third_element)

There's no reason you can't pass a function into another function as an argument!

Upvotes: 4

NPE
NPE

Reputation: 500307

Then lambda inside a sort? I am lost!

Basically, when sort() needs to compare two elements, it calls the lambda function and uses its result to determine which of the two elements should come first. This is all there is to it.

Upvotes: 4

Related Questions