Motmot
Motmot

Reputation: 121

How to order a list of tuples by second element given that it is already ordered by first element

So I have a list like this:

list_ = [(3, 2), (2, 2), (2, 1), (1, 3), (1, 2), (1, 1)]

And I would like to sort it so that the first elements remain in the same order i.e. 3, 2, 2, 1, 1, 1, but the second elements are ordered the opposite way so it's like this:

list_ = [(3, 2), (2, 1), (2, 2), (1, 1), (1, 2), (1, 3)]

I can't seem to think of a simple way of doing this. (I'm quite new to programming.

Edit: A further example would be to order this list:

[(2,3), (3,2), (1,3), (3,4), (5,1)]

So that it becomes this:

[(5,1), (3,2), (3,4), (2,3), (1,3)]

i.e. the tuples are ordered such that the first elements are in decreasing order and where the first element is the same the tuples are ordered with second elements in increasing order.

Upvotes: 0

Views: 813

Answers (3)

sumit-sampang-rai
sumit-sampang-rai

Reputation: 691

Try this:

print sorted(list_, key=lambda x:(-x[0],x[1]))

Output:

[(3, 2), (2, 1), (2, 2), (1, 1), (1, 2), (1, 3)]

Upvotes: 0

JuniorCompressor
JuniorCompressor

Reputation: 20025

You can group by first element and then sort the elements for each group:

from itertools import groupby
l = [(3, 2), (2, 2), (2, 1), (1, 3), (1, 2), (1, 1)]
l = [
    v for first, items in groupby(l, key=lambda x: x[0])
    for v in sorted(items, key=lambda x: x[1])
]

Result:

[(3, 2), (2, 1), (2, 2), (1, 1), (1, 2), (1, 3)]

If the first element has to be sorted in descending order, then you can sort first by second element and then stable sort by first element.

>>> l.sort(key=lambda x: x[1])
>>> l.sort(key=lambda x: x[0], reverse=True)
>>> l
[(3, 2), (2, 1), (2, 2), (1, 1), (1, 2), (1, 3)]

Upvotes: 2

hgazibara
hgazibara

Reputation: 1832

When sorting, you can define functions to be called prior to making the comparisons. One possible way which should work in your case is to define a function like this:

def get_key(item):
    return (-item[0], item[1])

This works because in Python it's possible to compare tuples by comparing values at the appropriate positions. This key function makes the sorting algorithm choose the pairs whose first element has the greatest values first, and then all ties are settled by choosing elements with smaller values first.

You could then sort the list by calling sorted and setting the parameter key to the previously described function.

>>> list_[(3, 2), (2, 2), (2, 1), (1, 3), (1, 2), (1, 1)]
>>>> sorted(list_, key=get_key)
[(3, 2), (2, 1), (2, 2), (1, 1), (1, 2), (1, 3)]

Upvotes: 0

Related Questions