I have a 2 dimensional list. I want to sort this list by multiple criteria in the sublist, but provide a default if one of the chosen index criteria doesn't exist.
my_list = [[5, 4], [1], [6, 8, 1]]
my_list.sort(key=lambda x: (x[0], x[1])
Obviously, this will throw an out of range error. How can I get around this and provide a default value if the index doesn't exist?
CodePudding user response:
You can write it the explicit way, checking length and using a different value if it's too short:
my_list.sort(key=lambda x: (x[0], x[1] if len(x) > 1 else 12345)
or you can append the fallback value unconditionally, then slice down to the number of elements you care about:
my_list.sort(key=lambda x: [*x, 12345][:2])
CodePudding user response:
In your lambda, you could add two default values (in this case I've used None
) to the end of the list ensuring it is at least two values long.
>>> my_list = [[5, 4], [1], [6, 8, 1]]
>>> sorted(my_list, key=lambda x: ((x := [*x, None, None])[0], x[1]))
[[1], [5, 4], [6, 8, 1]]
Requires Python 3.8 or later for :=
operator.
CodePudding user response:
You can take advantage of the fact that indexing a list with an out-of-bound slice returns an empty list, and use the or
operator to make the empty list default to a singleton list enclosing a value you want in its place. Since the or
operator is widely used as an idiom to provide default values, this approach makes the code arguably more readable:
DEFAULT = [1]
my_list.sort(key=lambda x: (x[0], x[1:2] or DEFAULT))