user_78361084
user_78361084

Reputation: 3908

How do I sort a list of datetime or date objects?

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

Upvotes: 119

Views: 289320

Answers (2)

cottontail
cottontail

Reputation: 23131

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)]

Upvotes: 10

Volatility
Volatility

Reputation: 32300

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.

Upvotes: 185

Related Questions