简体   繁体   中英

Python - Itemgetter on Dates

from operator import itemgetter

a=[['','27/01/2014'],['','28/01/2014'],['','29/01/2014'],['','30/01/2014'],['','31/01/2014'],['','01/02/2014'],['','02/02/2014']]

b=sorted(a,key=itemgetter(-1))

Output:

[['', '01/02/2014'], ['', '02/02/2014'], ['', '27/01/2014'], ['', '28/01/2014'], ['', '29/01/2014'], ['', '30/01/2014'], ['', '31/01/2014']]

Why is itemgetter producing this result?

I know in the example the dates are in ascending order, but suppose they weren't, is there a function that will do this simply?

The date is stored as a string, so sorting is performed lexicographically. If you want it sorted as a date, you should use datetime.strptime :

import datetime
b=sorted(a,key=lambda x:datetime.datetime.strptime(x[-1], '%d/%m/%Y'))

Output:

[['', '27/01/2014'], ['', '28/01/2014'], ['', '29/01/2014'], ['', '30/01/2014'], ['', '31/01/2014'], ['', '01/02/2014'], ['', '02/02/2014']]

They are sorted, as you asked. Of course, your dates are strings, and strings are sorted lexicographically . This is only equivalent to the natural sorting order of dates if your dates are in ISO 8601 format. Yours are not.

Try sorting by converting each to a datetime object in your key function:

sorted(a,key=lambda x: datetime.strptime(x[1],'%d/%m/%Y'))
Out[18]: 
[['', '27/01/2014'],
 ['', '28/01/2014'],
 ['', '29/01/2014'],
 ['', '30/01/2014'],
 ['', '31/01/2014'],
 ['', '01/02/2014'],
 ['', '02/02/2014']]

You don't have dates there. You have strings which happen to contain a string representation of a date. As such, when you sort by the strings, you are sorting it using standard lexicographical order .

If you want to sort it by date , you actually need to interpret those strings. For example with datetime:

>>> a = [['','27/01/2014'],['','28/01/2014'],['','29/01/2014'],['','30/01/2014'],['','31/01/2014'],['','01/02/2014'],['','02/02/2014']]
>>> a.sort(key=lambda x: datetime.strptime(x[-1], '%d/%m/%Y'))
>>> a
[['', '27/01/2014'], ['', '28/01/2014'], ['', '29/01/2014'], ['', '30/01/2014'], ['', '31/01/2014'], ['', '01/02/2014'], ['', '02/02/2014']]

If you want to work with the dates, it's probably a good idea to convert them to datetime objects anyway:

>>> b = [[a, datetime.strptime(b, '%d/%m/%Y')] for a, b in a]
>>> b
[['', datetime.datetime(2014, 1, 27, 0, 0)], ['', datetime.datetime(2014, 1, 28, 0, 0)], ['', datetime.datetime(2014, 1, 29, 0, 0)], ['', datetime.datetime(2014, 1, 30, 0, 0)], ['', datetime.datetime(2014, 1, 31, 0, 0)], ['', datetime.datetime(2014, 2, 1, 0, 0)], ['', datetime.datetime(2014, 2, 2, 0, 0)]]

And then you can also use itemgetter :

>>> from operator import itemgetter
>>> b.sort(key=itemgetter(-1))
>>> b
[['', datetime.datetime(2014, 1, 27, 0, 0)], ['', datetime.datetime(2014, 1, 28, 0, 0)], ['', datetime.datetime(2014, 1, 29, 0, 0)], ['', datetime.datetime(2014, 1, 30, 0, 0)], ['', datetime.datetime(2014, 1, 31, 0, 0)], ['', datetime.datetime(2014, 2, 1, 0, 0)], ['', datetime.datetime(2014, 2, 2, 0, 0)]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM