Willow
Willow

Reputation: 1466

Sort arbitrarily typed list with possible nulls

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 Nones 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

Answers (1)

Pychopath
Pychopath

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

Related Questions