Reputation: 57
I need to sort a list of lists by date:
mylist=['ML-M01 Qual Report 07/31/13', 'ML36220010 Complete Qual Testing 07/24/13', 'ML36220045 Final FRB 07/13/13', 'ML9822D2600 Brief to PM 08/5/13']
from this site, I got this code:
sorted(mylist, key=lambda x: datetime.datetime.strptime(x[2], '%m/%d/%y'))
however, I get this error message:
sorted(mylist,key=lambda x: datetime.datetime.strptime(x[2], '%m/%d/%y'))
Traceback (most recent call last):
File "<pyshell#25>", line 1, in <module>
sorted(mylist,key=lambda x: datetime.datetime.strptime(x[2], '%m/%d/%y'))
File "<pyshell#25>", line 1, in <lambda>
sorted(mylist,key=lambda x: datetime.datetime.strptime(x[2], '%m/%d/%y'))
File "C:\Python25\Lib\_strptime.py", line 330, in strptime
(data_string, format))
ValueError: time data did not match format: data=- fmt=%m/%d/%y
need help - need to sort the list by the 3d element - oldest to newest
Upvotes: 1
Views: 5623
Reputation: 1121446
Each entry in your list is a string, not a list, so x[2]
is a single character ('-'
for your first entry). You need to split out just the date portion to strptime()
:
sorted(mylist, key=lambda x: datetime.datetime.strptime(x.rsplit(None, 1)[-1], '%m/%d/%y'))
The str.rsplit()
splits on whitespace, once, for efficiency:
>>> 'ML-M01 Qual Report 07/31/13'.rsplit(None, 1)
['ML-M01 Qual Report', '07/31/13']
>>> 'ML-M01 Qual Report 07/31/13'.rsplit(None, 1)[-1]
'07/31/13'
Result:
>>> sorted(mylist, key=lambda x: datetime.datetime.strptime(x.rsplit(None, 1)[-1], '%m/%d/%y'))
['ML36220045 Final FRB 07/13/13', 'ML36220010 Complete Qual Testing 07/24/13', 'ML-M01 Qual Report 07/31/13', 'ML9822D2600 Brief to PM 08/5/13']
Note that sorted()
returns a new sorted list, the original list is not affected. If you want to sort mylist
in place, call the list.sort()
method on it:
mylist.sort(key=lambda x: datetime.datetime.strptime(x.rsplit(None, 1)[-1], '%m/%d/%y'))
Upvotes: 8
Reputation: 222822
Your error:
ValueError: time data did not match format: data=- fmt=%m/%d/%y
Indicates that you got data "-"
which is not a date. This indicates that you have lines in your list that won't contain a valid date.
This solution deals with invalid dates by returning None
. That will put all invalid dates together:
import datetime
mylist=['ML-M01 Qual Report 07/31/13', 'ML36220010 Complete Qual Testing 07/24/13', 'ML36220045 Final FRB 07/13/13', 'ML9822D2600 Brief to PM 08/5/13']
def extract_date(text):
try:
return datetime.datetime.strptime(text.rsplit(None, 1)[-1], '%m/%d/%y')
except ValueError:
return None
mylist.sort(key=extract_date)
print mylist
Output:
['ML36220045 Final FRB 07/13/13',
'ML36220010 Complete Qual Testing 07/24/13',
'ML-M01 Qual Report 07/31/13',
'ML9822D2600 Brief to PM 08/5/13']
Upvotes: 2