How to sort with lambda in Python

Question:

I am trying to sort some values by attribute, like so:

a = sorted(a, lambda x: x.modified, reverse=True)

I get this error message:

<lambda>() takes exactly 1 argument (2 given)

Why? How do I fix it?


This question was originally written for Python 2.x. In 3.x, the error message will be different: TypeError: sorted expected 1 argument, got 2.

Asked By: Niklas Rosencrantz

||

Answers:

Use

a = sorted(a, key=lambda x: x.modified, reverse=True)
#             ^^^^

On Python 2.x, the sorted function takes its arguments in this order:

sorted(iterable, cmp=None, key=None, reverse=False)

so without the key=, the function you pass in will be considered a cmp function which takes 2 arguments.

Answered By: kennytm
lst = [('candy','30','100'), ('apple','10','200'), ('baby','20','300')]
lst.sort(key=lambda x:x[1])
print(lst)

It will print as following:

[('apple', '10', '200'), ('baby', '20', '300'), ('candy', '30', '100')]
Answered By: Trillionaire Sanai

You’re trying to use key functions with lambda functions.

Python and other languages like C# or F# use lambda functions.

Also, when it comes to key functions and according to the documentation

Both list.sort() and sorted() have a key parameter to
specify a function to be called on each list element prior to making
comparisons.

The value of the key parameter should be a function that takes a single argument and returns a key to use for sorting purposes. This technique is fast because the key function is called exactly once for each input record.

So, key functions have a parameter key and it can indeed receive a lambda function.

In Real Python there’s a nice example of its usage. Let’s say you have the following list

ids = ['id1', 'id100', 'id2', 'id22', 'id3', 'id30']

and want to sort through its "integers". Then, you’d do something like

sorted_ids = sorted(ids, key=lambda x: int(x[2:])) # Integer sort

and printing it would give

['id1', 'id2', 'id3', 'id22', 'id30', 'id100']

In your particular case, you’re only missing to write key= before lambda. So, you’d want to use the following

a = sorted(a, key=lambda x: x.modified, reverse=True)
Answered By: Tiago Martins Peres

In Python3:

    from functools import cmp_to_key
    def compare(i1,i2):
      return i1-i2
    events.sort(key=cmp_to_key(compare))
Answered By: James L.

Take a look at this Example, you will understand:

Example 1:

a = input()
a = sorted(a, key = lambda x:(len(x),x))
print(a)

input: ["tim", "bob", "anna", "steve", "john","aaaa"]
output: ['bob', 'tim', 'aaaa', 'anna', 'john', 'steve']

input: ["tim", "bob", "anna", "steve", "john","aaaaa"]
output: ['bob', 'tim', 'anna', 'john', 'aaaaa', 'steve']


Example 2 (advanced):

a = ["tim", "bob", "anna", "steve", "john","aaaaa","zzza"]
a = sorted(a, key = lambda x:(x[-1],len(x),x))
print(a)

output: ['anna', 'zzza', 'aaaaa', 'bob', 'steve', 'tim', 'john']


Example 3 (advanced):

a = [[1,4],[2,5],[3,1],[1,6],[3,8],[4,9],[0,3],[2,6],[9,5]]
a = sorted(a, key = lambda x:(-x[1],x[0]))
print(a)

output: [[4, 9], [3, 8], [1, 6], [2, 6], [2, 5], [9, 5], [1, 4], [0, 3], [3, 1]]


Conclusion:

key = lambda x:(p1,p2,p3,p4,...,pn),
x is one element at a time from the stream of input.
p1,p2,p3...pn being properties based on which the stream of elements needs to be sorted.
based on priority order of p1>p2>p3>...>pn.
We can also add reverse=True, after the sorting condition, to sort the elements in reverse order.

Answered By: Albert Mathews