I'm sorting a list of dicts by a key:
groups = sorted(groups, key=lambda a: a['name'])
some of the dicts have name set to None
, and Python 2 places None
values before any other, so they're placed at the front of the sorted list. A naive fix would be
groups = sorted(groups, key=lambda a: a['name'] or 'zzzz')
but, obviously, that would not work for any non-Latin names.
What is a nice and Pythonic way of sorting a list containing None
values so that those values are placed at the end of the list?
Custom Sorting With key= For example with a list of strings, specifying key=len (the built in len() function) sorts the strings by length, from shortest to longest. The sort calls len() for each string to get the list of proxy length values, and then sorts with those proxy values.
sort() list provides a member function sort(). It Sorts the elements of list in low to high order i.e. if list is of numbers then by default they will be sorted in increasing order. Whereas, if list is of strings then, it will sort them in alphabetical order.
You can do this by keying it on a tuple:
groups = sorted(groups, key=lambda a: (a['name'] is None, a['name']))
This works because Python compares tuples lexicographically (on the first element, then on the second to break ties), and because False gets sorted earlier than True. A list of groups like
[{'name': 0}, {'name': 1}, {'name': 2}, {'name': 3}, {'name': 4}, {'name': None}]
will become
[(False, 0), (False, 1), (False, 2), (False, 3), (False, 4), (True, None)]
The tuple that starts with True
will necessarily end up at the end, and the rest, since the first value ties, will be sorted by the second value.
You can create your own "infinity" object:
from functools import total_ordering
@total_ordering
class Infinity:
def __eq__(self, other):
return type(other) == Infinity
def __lt__(self, other):
return False
Use it like so:
>>> lis = [{'name': 1}, {'name': None}, {'name': 0}, {'name': 2}]
>>> sorted(lis, key=lambda a: Infinity() if a['name'] is None else a['name'])
[{'name': 0}, {'name': 1}, {'name': 2}, {'name': None}]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With