blaufer
blaufer

Reputation: 119

Sorting a list of lists when not all the values exist

I am attempting to sort a list of lists but the inner lists have different lengths. For example:

version_list = [[1, 1, 2], [1, 0], [1, 3, 3], [1, 0, 12], [1, 0, 2], [2, 0, 0], [1, 1, 1]]

In the cases where there is no third value, it can be assumed to be 0. I have attempted to use:

revision = sorted(version_list, key=lambda x: (x[2] if x[2] >= 0 else x[2] = 0))

since I know that

revision = sorted(version_list, key=lambda x: x[1])
revision = sorted(version_list, key=lambda x: x[0])

both work otherwise.

The desired result would be:

[[1, 0], [1, 0, 2], [1, 0, 12], [1, 1, 1], [1, 1, 2], [1, 3, 3], [2, 0, 0]]

Any help or suggestions would be very much appreciated.

Upvotes: 1

Views: 149

Answers (3)

dr_dronych
dr_dronych

Reputation: 91

In support of Allen's answer, Python's sorted() built-in function works using the Timsort algorithm under the hood which does exactly what you want it to do: put the elements with less sub-elements in each first, e.g. [1, 0] is placed before [1, 0, 5].

Upvotes: 0

Allen Qin
Allen Qin

Reputation: 19957

Is this what you are after? Is seems by default sorted will do exactly what you need.

sorted(version_list)
Out[103]: [[1, 0], [1, 0, 2], [1, 0, 12], [1, 1, 1], [1, 1, 2], [1, 3, 3], [2, 0, 0]]

Upvotes: 0

MSeifert
MSeifert

Reputation: 152715

You can return a tuple in your key where the third value depends on the length of the sublist (using 0 if the sublist isn't length 3):

>>> sorted(version_list, key=lambda x: (x[0], x[1], x[2] if len(x) == 3 else 0))
[[1, 0], [1, 0, 2], [1, 0, 12], [1, 1, 1], [1, 1, 2], [1, 3, 3], [2, 0, 0]]

In case you want to sort on a specific index first you can shuffle the x[0], x[1] and x[2] if len(s) == 3 else 0 parts.

If you want it more generic you can also use an explicit function:

def padded(lst):
    desired_length = 3
    fallback_value = 0
    x = [fallback_value]*desired_length
    x[:len(lst)] = lst      # inserts list
    return x

sorted(version_list, key=padded)

However as noted in the comments (Dogan Askan), if there won't be negative values you don't need a key-function at all because list comparisons work (correctly in your sample case) even if the lengths differ:

sorted(version_list)  # no key function

Upvotes: 1

Related Questions