Python Sorting by Multiple Criteria

Python sorting by multiple criteria

List the three criteria in your key:

sorted(inputlist, key=lambda e: (len(e[0]), e[0], e[1]))

Now you are sorting each element first by the length, then by comparing the first element directly (which in only used when the first element is of equal length), then by the value of the last integer.

Python sorts tuples and lists like these lexicographically; compare the first element, and only if that doesn't differ, compare the second element, etc.

The second element here is e[0] which will only be used if both compared entries have nested lists of equal length. These are again compared lexicographically, so pairing up elements until a pair differs.

sorting by multiple criteria in Python

One solution could be:

sorted(players_results, key=lambda x:(-x[1],x[2]))

OUTPUT

[('Pierre', 1.0, 1), ('Matthieu', 1.0, 2), ('Joseph', 0.5, 3), ('Michel', 0.5, 5), ('Marie', 0.0, 4), ('Raphael', 0.0, 6)]

Sorting a Python list by two fields

like this:

import operator
list1 = sorted(csv1, key=operator.itemgetter(1, 2))

Sort a list by multiple attributes?

A key can be a function that returns a tuple:

s = sorted(s, key = lambda x: (x[1], x[2]))

Or you can achieve the same using itemgetter (which is faster and avoids a Python function call):

import operator
s = sorted(s, key = operator.itemgetter(1, 2))

And notice that here you can use sort instead of using sorted and then reassigning:

s.sort(key = operator.itemgetter(1, 2))

How to sort in python with multiple conditions?

every element is a list of 2 elements, sorting by the length of the list is useless because all of them has the same length, maybe you want to sort by the length of the first element so

finalresult = sorted(result, key=lambda word: (-word[1], len(word[0]), word[0]))

sort a python list based on multiple criteria

If the key returns a tuple, sorted will consider them in order when sorting:

In [3]: sorted(my_list, key=lambda k: (k['type'], k['val']), reverse=True)
Out[3]:
[{'type': 2, 'val': 6},
{'type': 1, 'val': 2},
{'type': 0, 'val': 9},
{'type': 0, 'val': 5}]

If you want the indices, just throw an enumerate in there as well:

In [7]: sorted(enumerate(my_list), key=lambda k: (k[1]['type'], k[1]['val']), reverse=True)
Out[7]:
[(1, {'type': 2, 'val': 6}),
(2, {'type': 1, 'val': 2}),
(3, {'type': 0, 'val': 9}),
(0, {'type': 0, 'val': 5})]

In [8]: [k for k, v in sorted(enumerate(my_list), key=lambda k: (k[1]['type'], k[1]['val']), reverse=True)]
Out[8]: [1, 2, 3, 0]

Sort list with multiple criteria in python

You can use the key argument of sorted function:

filenames = [
'1.0.0.0.py',
'0.0.0.0.py',
'1.1.0.0.py'
]

print sorted(filenames, key=lambda f: map(int, f.split('.')[:-1]))

Result:

['0.0.0.0.py', '1.0.0.0.py', '1.1.0.0.py']

The lambda splits the filename into parts, removes the last part and converts the remaining ones into integers. Then sorted uses this value as the sorting criterion.

Sorting keys of dictionary according to more than one criteria - Python 3.0

You can use lambda as a key function in sorted call

Following should get you the new dict in sorted order -

sorted_word_values_dict = dict(sorted(word_values_dict.items(), key=lambda x: (x[1], x[0])))

The key argument in sorted function can take a function which returns multiple values, in case there is a tie between the first value, the comparison would move to next value in the key.

In this example, x[1](dict value) would be compared first, if it is identical, we would compare the x[0](dict key).

Sorting an array of tuples in Python using multiple criteria both descending and ascending in value

You could multiply by -1 the second field:

my_list = [(1, 2, 3), (1, 3, 2), (2, 1, 3)]
my_list.sort(key=lambda tup: (tup[0], -1 * tup[1]), reverse=True)
print(my_list)

Output

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

General Solution

Note that multiplying by -1 is only going to work for numbers, for any other type of comparable objects (strings, tuples, etc), you could use a wrapper class like below:

@total_ordering
class neg:

def __init__(self, val):
self.val = val

def __eq__(self, other):
return self.val == other.val

def __lt__(self, other):
"""Should return the inverse value of self.val.__lt__(other)"""
return self.val >= other.val

and then use it like this:

my_list.sort(key=lambda tup: (tup[0], neg(tup[1])), reverse=True)
print(my_list)

Output (using wrapper class)

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

For more on the total_ordering class decorator, see the documentation and for the __lt__ method read this.



Related Topics



Leave a reply



Submit