120

How do I sort a list of date and/or datetime objects? The accepted answer here isn't working for me:

from datetime import datetime,date,timedelta

a=[date.today(), date.today() + timedelta(days=1), date.today() - timedelta(days=1)]
print(a) # [datetime.date(2013, 1, 22), datetime.date(2013, 1, 23), datetime.date(2013, 1, 21)]
a = a.sort()
print(a) # prints 'None'....what???
3
  • 1
    lst.sort() is an inplace operation Commented Jan 23, 2013 at 5:06
  • 1
    Did you read inplace operation? Why would the method return something that is performed on the existing datastructure? No new list is created and the existing list is not returned. This is completely intentional and documented behavior, brother. Commented Jan 23, 2013 at 5:10
  • 1
    I used sorted() operating on a list comprehension as follows: sorted([datetime.strptime(dt, "%Y-%m-%d %H:%M:%S") for dt in dateList]) . My dates were strings that looked like: '2018-09-07 19:00:46' Commented Oct 21, 2018 at 16:00

2 Answers 2

185

You're getting None because list.sort() it operates in-place, meaning that it doesn't return anything, but modifies the list itself. You only need to call a.sort() without assigning it to a again.

There is a built in function sorted(), which returns a sorted version of the list - a = sorted(a) will do what you want as well.

Sign up to request clarification or add additional context in comments.

2 Comments

which way is best? do they do same things under the covers?
@radtek list.sort() changes the object from which it is invoked (which is always a list). sorted() works on any iterable, not only list. list.sort() might be a little faster if you have a very large list because sorted() creates a new list and needs to copy the elements to it.
10

If your list contains a list of strings that look like datetime, you can sort them using a datetime parser as key.

For example, to sort lst, you can pass a lambda that parses each string into datetime as key (for a full list of possible formats, see https://strftime.org/).

from datetime import datetime, date
lst = ['02/01/2023 12:25 PM', '01/22/2023 11:00 PM', '12/01/2022 02:23 AM']
sorted_lst = sorted(lst, key=lambda x: datetime.strptime(x, '%m/%d/%Y %I:%M %p'))
# ['12/01/2022 02:23 AM', '01/22/2023 11:00 PM', '02/01/2023 12:25 PM']

# in-place sorting is also possible
lst.sort(key=lambda x: datetime.strptime(x, '%m/%d/%Y %I:%M %p'))

Of course, you can parse them into datetime first and then sort but that would change the type of the items in the list from str to datetime as you can see below:

new_lst = sorted(datetime.strptime(x, '%m/%d/%Y %I:%M %p') for x in lst)
# [datetime.datetime(2022, 12, 1, 2, 23), datetime.datetime(2023, 1, 22, 23, 0), datetime.datetime(2023, 2, 1, 12, 25)]

If your list is a mixture of date and datetimes, you can normalize them all into datetime objects, and then sort; again, as a key so that the type of the items in the original list doesn't change.

lst = [datetime(2013, 1, 21, 6, 14, 47), date(2013, 1, 22), date(2013, 1, 21)]
new_lst = sorted(lst, key=lambda x: x if isinstance(x, datetime) else datetime(x.year, x.month, x.day))
# [datetime.date(2013, 1, 21), datetime.datetime(2013, 1, 21, 6, 14, 47), datetime.date(2013, 1, 22)]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.