我在尝试对CSV文件进行排序,并且希望按相反顺序按日期排序项目:newest first。在Python中按日期排序CSV
def SortCsvByField(filename, fieldNo, sep = ','):
records = [line.split(sep) for line in file(filename)]
只要这很容易,但我如何比较日期?
我在尝试对CSV文件进行排序,并且希望按相反顺序按日期排序项目:newest first。在Python中按日期排序CSV
def SortCsvByField(filename, fieldNo, sep = ','):
records = [line.split(sep) for line in file(filename)]
只要这很容易,但我如何比较日期?
我建议安装优秀的dateutil模块。 (在Ubuntu/Debian中,它是由python-dateutil包提供的)。
dateutil可以解析日期字符串到datetime对象:它可以处理许多不同的日期格式,您无需动一根手指(*):
import dateutil.parser as dparser
date=dparser.parse("Mon May 7 1883 10:36:28")
print(date)
# 1883-05-07 10:36:28
date=dparser.parse("1685-3-21")
print(date)
# 1685-03-21 00:00:00
date=dparser.parse("12/17/1770")
print(date)
# 1770-12-17 00:00:00
注意,解析被训释“1770年12月17日”形式为“MM/DD/YYYY”。您可以使用解析的dayfirst
和yearfirst
选项更改此行为。 (见http://labix.org/python-dateutil)
print(type(date))
# <type 'datetime.datetime'>
datetime对象可以很容易地进行排序:
dates=[dparser.parse("Mon May 7 1883 10:36:28"),dparser.parse("1685-3-21"),dparser.parse("12/17/1770"),]
dates.sort()
print(dates)
# [datetime.date(1685, 3, 21), datetime.date(1770, 12, 17), datetime.date(1833, 5, 7)]
如果您不想安装dateutil包,那么你就必须 推出自己的转换日期字符串的方法到日期时间对象中。这需要更多的工作,因为您必须定义格式。在下面,'%Y-%m-%d'定义了YYYY-MM-DD格式。有关可用格式代码的更多信息,请参见http://au2.php.net/strftime(或strftime的手册页)。
例如,
dates=[datetime.datetime.strptime(date_str,'%Y-%m-%d') for date_str in
('1883-5-7','1685-3-21','1770-12-17',)]
print([str(date) for date in dates])
# ['1883-05-07 00:00:00', '1685-03-21 00:00:00', '1770-12-17 00:00:00']
dates.sort()
print([str(date) for date in dates])
# ['1685-03-21 00:00:00', '1770-12-17 00:00:00', '1883-05-07 00:00:00']
要控制格式转换时datetime对象返回到可打印的字符串,可以使用datetime.datetime.strftime()方法。
(1)“如果你使用的是Linux “??有关于dateutil的平台依赖吗?它似乎在Windows上正常工作[但参见下面的第3点](2)日期前面有'#'例如'#2009-09-25 10:36:28'?从print()输出?如果是这样,他们是错的。应该是例如(3)对于那些坚持“DD/MM/YYYY”公约的人来说,它将把'01/02/2009''解释为二月的第一天,手指,会吗?它不会像12月31日那样默默地采取“31/12/2008”''而在1月2日也采取'01/02/2009''是否会令人讨厌? – 2009-11-21 09:16:44
这是一个很好的开始,但是你没有解决它默认情况下接受混合dd/mm和mm/dd日期的问题(AFAICT)无法选择“严格”行为。 – 2009-11-21 21:01:20
我不明白为什么它默认追加10-19到'月份,日期'的日期。例如1946 - > 1946-10-19和46 - > 2046-10-19 ..我们可以更改默认行为吗? – ThinkCode 2010-10-19 19:13:25
你表现的很容易,但也很脆弱。
最好是使用Python的CSV库:http://docs.python.org/library/csv.html
关于比较日期(我假设一些日期是在每行特定的列),你可以使用datetime模块:http://docs.python.org/library/datetime.html。您可以在日期对象上使用标准比较运算符。
如果您的日期采用ISO-8601格式(YYYY-MM-DD),那么您可以将它们排序为字符串,否则您必须先解析它们(datetime.strptime)。
然后,您可以使用例如sorted(records, key=lambda a:a[1])
进行排序,如果日期是第二个字段。
假设你知道的日期格式,以及他们在您的CSV文件的第1列:
>>> import csv
>>> from datetime import datetime
>>> def date_key(row):
return datetime.strptime(row[1].strip(), "%m/%d/%Y")
>>> with open('c:\\temp\\test\\date_test.csv', 'rb') as f:
data = list(csv.reader(f))
>>> data
[['foo', ' 3/11/2004'], ['bar', ' 2/15/2001'], ['baz', '11/15/2007'], ['bat', '10/13/2002']]
>>> data.sort(key=date_key)
>>> data
[['bar', ' 2/15/2001'], ['bat', '10/13/2002'], ['foo', ' 3/11/2004'], ['baz', '11/15/2007']]
这取决于日期格式 – SilentGhost 2009-11-20 23:49:33