jobin
jobin

Reputation: 2798

Sorting a list of tuples on multiple keys

I want to sort a list of tuples where the tuples are of type (a, b) where a and b are integers. The key for sorting the list should be the difference between a and b i.e a - b and to break the ties, it should sort on a, both in descending order.

I tried using this:

def sort(list):
        scores = sorted(list, key=lambda list: list[0], reverse=True)
        scores = sorted(list, key=lambda list: (a - b), reverse=True)

But this seems to sort on the difference and reorder the elements sorted on the first element of the tuple.

For example:

The input:

[(75, 10),  (88, 4), (93, 9), (80, 5), (94, 10)]

The expected output:

[(94, 10), (93, 9), (88, 4), (80, 5), (75, 10)]

The obtained output:

[(93, 9), (88, 4), (94, 10), (80, 5), (75, 10)]

Upvotes: 2

Views: 1871

Answers (5)

Cawb07
Cawb07

Reputation: 2127

Sorry I didn't break the ties :/. I got the ordering without using anything complicated... here:

def sort(list):
    scores = sorted(list, key=lambda a: a[0], reverse=True)

    return scores

print sort([(75, 10),  (88, 4), (93, 9), (80, 5), (93, 11), (94, 10)])

Console:

[(94, 10), (93, 9), (93, 11), (88, 4), (80, 5), (75, 10)]

When I sort on differences, a-b, this is the result:

def sort(list):

    scores = sorted(list, key=lambda a: a[0], reverse=True)
    scores = sorted(list, key=lambda a: a[0]-a[1], reverse=True)

    return scores

print sort([(75, 10),  (88, 4), (93, 9), (80, 5), (93, 11), (94, 10)])

Console:

[(88, 4), (93, 9), (94, 10), (93, 11), (80, 5), (75, 10)]

Upvotes: 0

johnsyweb
johnsyweb

Reputation: 141790

To get the ordering you are looking for, sort using a compound key:

def sort(l):
    scores = sorted(l, key=lambda(e): (e[0] - e[1], e[0]), reverse=True)

This will yield:

scores = [(94, 10), (93, 9), (88, 4), (80, 5), (75, 10)]

N.B: list is a keyword and should not be used as a variable name.

Upvotes: 1

Graeme Stuart
Graeme Stuart

Reputation: 6053

The key lambda wants one input value (a tuple is OK)

sorted(data, key=lambda (a, b): (a-b, a), reverse=True)

Upvotes: 1

Hari Menon
Hari Menon

Reputation: 35405

list_sorted = sorted(list, key = lambda x: (x[0]-x[1], x[0]), reverse=True)

The lambda for key can return tuples whose order can indicate the sort priorities.

Upvotes: 1

agf
agf

Reputation: 176780

You can sort on a compound key:

>>> def sort(list):
...     return sorted(list, key=(lambda (a, b): ((a - b), a)), reverse=True)
... 
>>> sort([(75, 10),  (88, 4), (93, 9), (80, 5), (94, 10)])
[(94, 10), (93, 9), (88, 4), (80, 5), (75, 10)]

See the Python Wiki Sorting Howto for some nice tips.

Upvotes: 4

Related Questions