Glen
Glen

Reputation: 57

i need to sort a python list of lists by date

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

Answers (2)

Martijn Pieters
Martijn Pieters

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

nosklo
nosklo

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

Related Questions