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]]]
Asked By: Piotr Wasilewicz

||

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
Answered By: Marek

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)
Answered By: Kelly Bundy
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.