Sorting list of lists
Sorting nested list by 2 attributes / different order?
How do I sort a list with sublists with multiple ascending and descending criteria?
python - Sort list of lists ascending and then descending - Stack Overflow
Hello - i would like to sort a nested list for 2 attributes - but the first 1 attribute should be sorted descending and the second ascending -
Its clear for me how to sort both attributes descending with
l.sort(key=lambda x: (x[0], x[1]), reverse=True)
But how can i sort the first attribute descending and the second atttribut ascending?
For example, if I have a list :
list = [ [-10, 1, 3], [2, -5, 29], [3, -5, 0], [0, 0, -1] ]
And I want to sort the list with the following criteria in order :
For i in list :
-
sort
i[2](in ascending order) -
sort
i[0](in descending order) -
sort
i[1](in ascending order)
I've tried rearranging by using list comprehension and *-1 on the index I want to sort in descending order, then sort the rearranged list ( ex : newlist = [ [i[2], -i[0], i[1]] for i in list ] then newlist.sort() ) However, *-1 for descending order doesn’t work since some numbers are already negative, so that’s like where I’m stuck with. Any idea how to do this?
By the way, I cannot use dict, numpy, tuple, set or import any libraries since this is my college homework and my professor doesn’t allow us to use any of those.
L = [['a',1], ['a',2], ['a',3], ['b',1], ['b',2], ['b',3]]
L.sort(key=lambda k: (k[0], -k[1]), reverse=True)
L now contains:
[['b', 1], ['b', 2], ['b', 3], ['a', 1], ['a', 2], ['a', 3]]
You can do successive rounds of sorting as python's sort is stable. You need to first sort on the secondary key though. See also the official HOW TO.
from operator import itemgetter
l = [['a',2], ['a',1], ['b', 2], ['a',3], ['b',1], ['b',3]]
l.sort(key=itemgetter(1))
l.sort(key=itemgetter(0), reverse=True)
# [['b', 1], ['b', 2], ['b', 3], ['a', 1], ['a', 2], ['a', 3]]
Python automatically sorts lists of lists by the first element. For example:
lol=[[1,2,3],[5,6,7],[0,9,9]]
sorted(lol)
[[0, 9, 9], [1, 2, 3], [5, 6, 7]]
You want to use .sort() or sorted:
>>> t = [['D', 'F', 'E', 'D', 'F', 'D'], ['A', 'F', 'E', 'C', 'F', 'E'], ['C', 'E', 'E', 'F', 'E', 'E'], ['B', 'F', 'E', 'D', 'F', 'F']]
>>> t.sort(key=lambda x: x[0]) # changes the list in-place (and returns None)
>>> t
[['A', 'F', 'E', 'C', 'F', 'E'], ['B', 'F', 'E', 'D', 'F', 'F'], ['C', 'E', 'E', 'F', 'E', 'E'], ['D', 'F', 'E', 'D', 'F', 'D']]
Also note that your list needs commas between its elements. Here is the result for sorted:
>>> sorted(t) # does not change the list but returns the sorted list
[['A', 'F', 'E', 'C', 'F', 'E'], ['B', 'F', 'E', 'D', 'F', 'F'], ['C', 'E', 'E', 'F', 'E', 'E'], ['D', 'F', 'E', 'D', 'F', 'D']]
As you can see, the latter example sorts the lists without any key argument. The former example can as well; but you mention that only the first element is a unique identifier, so there is no way to tell what the secondary criteria might be for sorting the list beyond the first element.
Hi, I’m new to Python and was curious how to sort a list by the second dimension elements. For example, say I had a list that’s like:
[‘apple’, 20] [‘orange’, 12] [‘grape’, 16] [‘banana’, 23]
How would I sort the list by the numbers and not the words?
By default, sorted will use the first element:
>>> l1 = [[1,'steve'],[4,'jane'],[3,'frank'],[2,'kim']]
>>> sorted(l1)
[[1, 'steve'], [2, 'kim'], [3, 'frank'], [4, 'jane']]
As noted in the comments, l1.sort() will sort the original list in place, and is a better option if you don't need to preserve the original order.
This is the way the comparison operators work in Python:
>>> [1, 'something'] < [2, 'something']
True
Note that if the first element compares as equal, it will compare the second element, and so on:
>>> [1, 1, 1] < [1, 1, 2]
True
This means that two names with the same number would be sorted (lexicographically) by the string, not in place:
>>> sorted([[1, 'mike'], [1, 'bob']])
[[1, 'bob'], [1, 'mike']]
Python sort will compare the lists with the first element by default. If they're the same, it will continue with the second element, and so on.
so
l1.sort()
will do.
But if you really just want to sort by first value and nothing else :
sorted(l1, key=lambda id_and_name: id_and_name[0])
#=> [[1, 'steve'], [2, 'kim'], [3, 'frank'], [4, 'jane']]
Use sorted function along with passing anonymous function as value to the key argument. key=lambda x: x[0] will do sorting according to the first element in each sublist.
>>> lis = [[1,4,7],[3,6,9],[2,59,8]]
>>> sorted(lis, key=lambda x: x[0])
[[1, 4, 7], [2, 59, 8], [3, 6, 9]]
If you're sorting by first element of nested list, you can simply use list.sort() method.
>>> lis = [[1,4,7],[3,6,9],[2,59,8]]
>>> lis.sort()
>>> lis
[[1, 4, 7], [2, 59, 8], [3, 6, 9]]
If you want to do a reverse sort, you can use lis.reverse() after lis.sort()
>>> lis.reverse()
>>> lis
[[3, 6, 9], [2, 59, 8], [1, 4, 7]]