# How to sort nested lists when first elements match?

2591 views
0

I have a nested list which is sorted based on the first elements of each sublist:

``````t = [['2', '5'], ['8', '10'], ['8', '2'], ['8', '5'], ['9', '0']]
``````

How can I now sort the sublists which start with the same element, by the next element without affecting the other sublists?

For example sorting t, t and t whilst maintaining the order of the other sub-lists:

``````sort_by_all(t)
>> [['2', '5'], ['8', '2'], ['8', '5'], ['8', '10'], ['9', '0']]
``````

My logic is to first find all sublists which start with the same element, sort them by their second element and then somehow put these back into the original list. Just `sorted(t)`. The default way of ordering is lexicographically. Note that if values are larger than `9`, `'10'`, will be sorted between `'1'` and `'2'`

8

`sorted` and `list.sort` can both sort lexicographically. In other words, you can pass in a key that returns a sequence. In this case, you want to convert any values to integers first.

``````t = [['2', '5'], ['8', '10'], ['8', '2'], ['8', '5'], ['9', '0']]
# Create new list
print(sorted(t, key=lambda seq: (int(seq), int(seq))))
# Or, sort in place
t.sort(key=lambda seq: (int(seq), int(seq)))
print(t)

# Output
[['2', '5'], ['8', '2'], ['8', '5'], ['8', '10'], ['9', '0']]
[['2', '5'], ['8', '2'], ['8', '5'], ['8', '10'], ['9', '0']]
``````

If you want it to work for list with greater than two elements per sublist, replace the key with this:

``````lambda seq: [int(i) for i in seq]
``````

posted this
13

My logic is to first find all sublists which start with the same element, sort them by their second element and then somehow put these back into the original list.

The default ordering of a list and tuple is lexicographically. That means that Python will first compare the first elements of the list/tuple, if these match, it will advance to the next elements, etc.

A problem here is that `'10'` is sorted between `'1'` and `'2'`. Given the strings are representations of integers, we can fix this by mapping the elements over the `int` constructor first.

You can thus call `t.sort(..)` on the list, or `sorted(t)` if you want to construct a new list. For example:

``````>>> t = [['2', '5'], ['8', '10'], ['8', '2'], ['8', '5'], ['9', '0']]
>>> t.sort(key=lambda l: list(map(int, l)))
>>> t
[['2', '5'], ['8', '2'], ['8', '5'], ['8', '10'], ['9', '0']]
``````

posted this