How to sort a list and handle None values ​​correctly?

I am trying to sort a list of objects using the date attribute with

list_of_objects.sort(key=lambda x: x.date, reverse=True) 

but some dates are just None, which means I get an error

 TypeError: can't compare datetime.datetime to NoneType 

Is there any way to account for this? for example, are there objects with date == None at the top or bottom of the sorted list - or do I need to do this manually?

+7
python
source share
3 answers

You can change your lambda slightly:

 from datetime import datetime list_of_objects.sort(key=lambda x: x.date or datetime.min, reverse=True) 

If they appear at the wrong end of the sort, use datetime.max .

+14
source share

You want to sort based on two properties:

  • First of all, is there a date
  • Secondly, date (if present)

You can express your intention in a simple way, sorting by tuple where

  • the first element of the tuple indicates whether the date is None and
  • the second element of the tuple is the date itself.
 list_of_objects.sort(key=lambda x: (x.date is None, x.date), reverse=True) 

This approach bypasses the type error you get, because the comparison between tuples is done lazily-right lazily. The second element of the tuple is not compared if the first elements are not equal.

Here are a few examples to demonstrate the concept:

 >>> xs = [None, 1, 3, None, 2] >>> sorted(xs, key=lambda x: (x is None, x)) [1, 2, 3, None, None] >>> sorted(xs, key=lambda x: (x is not None, x)) [None, None, 1, 2, 3] >>> sorted(xs, key=lambda x: (x is None, x), reverse=True) [None, None, 3, 2, 1] >>> sorted(xs, key=lambda x: (x is not None, x), reverse=True) [3, 2, 1, None, None] 
+12
source share

Maybe you should filter out dates that aren't Firsts before sorting.

0
source share

All Articles