Reputation: 1466
I have a bunch of lists (they come from a database) and I want to sort each one as best I can. However, I don't know the types beforehand. Since they are from db, mostly there will be dates, datetimes, strings, numbers, and booleans.
Most of the values in a given list will be of the same type, but there will be pesky None
s in there sometimes (the db fields are mostly nullable).
Usually if I knew the type of the list beforehand I would use something like this as my key
:
lambda el: el or 0
but replace 0 with whatever is most appropriate (ie -math.inf
, ""
, datetime.datetime.fromtimestamp(0)
, etc)
Here's what I've come up with:
def sort_arbitrarily_typed_list(my_list):
try:
# Ideal situation - no nulls, all is happy
return sorted(my_list)
except:
pass
try:
# Maybe it's numbers?
return sorted(my_list, key=lambda el: el or 0)
except:
pass
try:
# Maybe strings?
return sorted(my_list, key=lambda el: el or "")
except:
# Catchall: just convert everything to a string and compare them.
return sorted(my_list, key=str)
Are there any problems with this approach, or is there maybe a better way? I figured str
as the catchall would be fine...is there any case where calling str
on a value will fail?
Upvotes: 0
Views: 70
Reputation: 1580
You could sort primarily by None
-ness and secondarily by value, so it won't do comparisons of None
and other values.
>>> my_list = [3, None, 1, None, 4]
>>> sorted(my_list, key=lambda x: (x is None, x))
[1, 3, 4, None, None]
Upvotes: 2