Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order list by date (String and datetime)

import csv,operator
from datetime import datetime

li = [['name','01/03/2012','job'],
      ['name','02/05/2013','job'],
      ['name','03/08/2014','job']]

Sorted Method:

sorted(li,key=lambda x:datetime.strptime(row[1],'%d/%m/%Y'), reverse=True)

Output:

No error, but simply not ordered

Itemgetter Method:

for x in range(1,len(li)):
    li[x][6]=datetime.strptime(li[x][6],'%d/%m/%Y')

li.sort(key=operator.itemgetter(6))

Output:

Traceback (most recent call last):
  File "U:/rmarshall/Work For Staff/ROB/_Python/__Python Projects Code/April Signed Terms.py", line 35, in <module>
    li.sort(key=operator.itemgetter(6))
TypeError: unorderable types: datetime.datetime() < str()

Could someone supply an example of ordering a the list li by date. For educational purposes I would appreciate examples of both the sorted method and itemgetter method with a comparison of efficiency.

Also, by the error on the itemgetter approach, is itemgetter simply not able to handle datetime objects.

Note: I presume the ascending or descending order doesn't matter too much in this example as it can be simply flipped with reverse=True.

like image 837
Phoenix Avatar asked Apr 04 '14 09:04

Phoenix


3 Answers

This should work.

print(sorted(li, key=lambda x: datetime.strptime(x[1], '%d/%m/%Y'), reverse=True))

You used row in the lamba which might have been defined before, but will never change.

I don't see a way to use itemgetter here. To be honest, there is a way, but it doesn't look good.

key_function = lambda x: datetime.strptime(itemgetter(1)(x), '%d/%m/%Y') 
print(sorted(li, key=key_function, reverse=True))
like image 169
Matthias Avatar answered Sep 24 '22 23:09

Matthias


The following works:

>>> sorted(li, key=lambda x: datetime.strptime(x[1], "%d/%m/%Y"), reverse=True)
[['name', '03/08/2014', 'job'], ['name', '02/05/2013', 'job'], ['name', '01/03/2
012', 'job']]

The problem with your use of the sorted() is that you're trying to create a datetime from row[1] which doesn't work. Change it to the lambda you created, as I've shown above.

You most likely have a row variable defined somewhere earlier, which is why it will not raise an error. However if I run the following:

>>> sorted(li,key=lambda x:datetime.strptime(row[1],'%d/%m/%Y'), reverse=True)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<input>", line 1, in <lambda>
NameError: global name 'row' is not defined

Here's an example with itemgetter:

>>> sorted(l, key=itemgetter(1))
[['name', '01/03/2012', 'job'], ['name', '02/05/2013', 'job'], ['name', '03/08/2014', 'job']]

In your case it works, because your datestrings are in the correct format. It might still be prudent to convert them to datetime objects.

like image 32
msvalkon Avatar answered Sep 22 '22 23:09

msvalkon


You have to convert str to datetime, because sorted, can't compare datetime and str.

datetime.strptime use to convert str to datetime object.

You can use list.sort on to sort on same list.

In [43]: li.sort(key=lambda x: datetime.strptime(x[1], "%d/%m/%Y"))

In [44]: li
Out[44]:
[['name', '01/03/2012', 'job'],
 ['name', '02/05/2013', 'job'],
 ['name', '03/08/2014', 'job']]
like image 45
Nilesh Avatar answered Sep 23 '22 23:09

Nilesh