How to sort liberally-deep list of lists and integers?
Question:
Let’s say I have a list like that:
[[5, [2, 1], 3], [3, [8, 7], [2, 1, 3], 2], [[3, 2, 1], 3, -1]]
(each list can store unspecified number of integers and lists in any order).
Rules for sorting:
- integers (if any) should be before any list
- integers are sorted normally (from lower to higher value)
- list is "smaller" than another when the first element is lower, if the same we consider the second element, the third, and so on.
- If the list has the same values as another but less, it’s smaller.
[1, 2] < [1, 2, 3]
So the final result should be:
[[-1, 3, [1, 2, 3]], [2, 3, [1, 2, 3], [7, 8]], [3, 5, [1, 2]], ]
How to implement that kind of sorting? I’ve tried to pass recursive function as sort
key in sorted
, but mostly ended with TypeError (<
not supported for int
and list
).
Another example:
[1, 4, 3, [[5, 7, 1, 2], 2, 5, 10, 2], 8, [2, 5, [5, 3, 3]], [2, 5, 10, 2, [1, 2, 5]]]
After sorting :
[1, 3, 4, 8, [2, 2, 5, 10, [1, 2, 5]], [2, 2, 5, 10, [1, 2, 5, 7]], [2, 5, [3, 3, 5]]]
Answers:
Quick draft:
def big_brain_sort(li: list) -> list:
list_with_int = []
list_with_list = []
for el in li:
if isinstance(el, int):
list_with_int.append(el)
elif isinstance(el, list):
list_with_list.append(big_brain_sort(el))
sorted_list_int = sorted(list_with_int)
for lista in sorted(list_with_list, key=lambda x: (big_brain_sort(x), len(x))):
sorted_list_int.append(lista)
return sorted_list_int
Edit: broken, see comments
You could sort in-place with this key function:
def key(x):
if isinstance(x, int):
return 0, x
x.sort(key=key)
return 1, x
Demo (reporting True
for both test cases, Try it online!):
def key(x):
if isinstance(x, int):
return 0, x
x.sort(key=key)
return 1, x
given = [[5, [2, 1], 3], [3, [8, 7], [2, 1, 3], 2], [[3, 2, 1], 3, -1]]
wanted = [[-1, 3, [1, 2, 3]], [2, 3, [1, 2, 3], [7, 8]], [3, 5, [1, 2]], ]
given.sort(key=key)
print(given == wanted)
given = [1, 4, 3, [[5, 7, 1, 2], 2, 5, 10, 2], 8, [2, 5, [5, 3, 3]], [2, 5, 10, 2, [1, 2, 5]]]
wanted = [1, 3, 4, 8, [2, 2, 5, 10, [1, 2, 5]], [2, 2, 5, 10, [1, 2, 5, 7]], [2, 5, [3, 3, 5]]]
given.sort(key=key)
print(given == wanted)
Let’s say I have a list like that:
[[5, [2, 1], 3], [3, [8, 7], [2, 1, 3], 2], [[3, 2, 1], 3, -1]]
(each list can store unspecified number of integers and lists in any order).
Rules for sorting:
- integers (if any) should be before any list
- integers are sorted normally (from lower to higher value)
- list is "smaller" than another when the first element is lower, if the same we consider the second element, the third, and so on.
- If the list has the same values as another but less, it’s smaller.
[1, 2] < [1, 2, 3]
So the final result should be:
[[-1, 3, [1, 2, 3]], [2, 3, [1, 2, 3], [7, 8]], [3, 5, [1, 2]], ]
How to implement that kind of sorting? I’ve tried to pass recursive function as sort
key in sorted
, but mostly ended with TypeError (<
not supported for int
and list
).
Another example:
[1, 4, 3, [[5, 7, 1, 2], 2, 5, 10, 2], 8, [2, 5, [5, 3, 3]], [2, 5, 10, 2, [1, 2, 5]]]
After sorting :
[1, 3, 4, 8, [2, 2, 5, 10, [1, 2, 5]], [2, 2, 5, 10, [1, 2, 5, 7]], [2, 5, [3, 3, 5]]]
Quick draft:
def big_brain_sort(li: list) -> list:
list_with_int = []
list_with_list = []
for el in li:
if isinstance(el, int):
list_with_int.append(el)
elif isinstance(el, list):
list_with_list.append(big_brain_sort(el))
sorted_list_int = sorted(list_with_int)
for lista in sorted(list_with_list, key=lambda x: (big_brain_sort(x), len(x))):
sorted_list_int.append(lista)
return sorted_list_int
Edit: broken, see comments
You could sort in-place with this key function:
def key(x):
if isinstance(x, int):
return 0, x
x.sort(key=key)
return 1, x
Demo (reporting True
for both test cases, Try it online!):
def key(x):
if isinstance(x, int):
return 0, x
x.sort(key=key)
return 1, x
given = [[5, [2, 1], 3], [3, [8, 7], [2, 1, 3], 2], [[3, 2, 1], 3, -1]]
wanted = [[-1, 3, [1, 2, 3]], [2, 3, [1, 2, 3], [7, 8]], [3, 5, [1, 2]], ]
given.sort(key=key)
print(given == wanted)
given = [1, 4, 3, [[5, 7, 1, 2], 2, 5, 10, 2], 8, [2, 5, [5, 3, 3]], [2, 5, 10, 2, [1, 2, 5]]]
wanted = [1, 3, 4, 8, [2, 2, 5, 10, [1, 2, 5]], [2, 2, 5, 10, [1, 2, 5, 7]], [2, 5, [3, 3, 5]]]
given.sort(key=key)
print(given == wanted)