2

我有一个字典,其中字符串作为键,格式为 yyyy-mm-dd,并希望按最早日期的键对字典进行排序:

我目前正在使用sorted(datesAndText.keys()),但这并不可靠,因为月份和日期字段并不总是填充零。

我查看了按日期键对 python 字典进行排序以及如何在 Python 中对这个列表进行排序,如果我的日期在字符串中?但我似乎无法根据具体情况采用它们。

4

3 回答 3

8

您确定您的密钥完全符合格式yyyy-mm-dd吗?例如:

>>> '2010-1-15' < '2010-02-15'
False

您可能会被迫对以下内容进行排序:

sorted(d,key=lambda x: [int(y) for y in x.split('-')])

另一种解决方案(假设您的年份都是 4 位数):

sorted(d,key=lambda x: [y.zfill(2) for y in x.split('-')]) 

我不确定哪个会更快。我想这是一个候选人timeit

于 2012-10-10T13:56:43.487 回答
2

格式中的日期yyyy-mm-dd按字母顺序和时间顺序排序相同,因此您可以使用标准sorted

for k, v in sorted(datesAndText.items()):
    # do something with key and value
于 2012-10-10T13:53:18.823 回答
2

您的格式 ,yyyy-mm-dd允许字典排序,因此您的代码应该可以正常工作,除非您的值不是零填充(例如2012-10-9而不是2012-10-09)。

通过比较日期而不是字符串来解决这个问题:

sorted(datesAndText, key=lambda x: datetime.strptime(x, '%Y-%m-%d'))

这利用了keysorted 参数,该参数是一个函数,它接受一个参数(在排序期间比较的列表元素)并返回一个sorted可用于排序的值。

如果您的数据需要更改,这具有允许您显式指定日期的字符串格式的辅助好处。

编辑:

mgilson提出了一个有趣的观点。 str.split可能更有效。让我们看看他是否正确:

strptime解决方案:

bburns@virgil:~$ python -mtimeit -s"from datetime import datetime;d={'2012-2-12':None, '2012-10-9':None, '1978-1-1':None, '1985-10-9':None}" 'sorted(d, key=lambda x: datetime.strptime(x,"%Y-%m-%d"))'
10000 loops, best of 3: 79.7 usec per loop

mgilson的原始str.split解决方案:

bburns@virgil:~$ python -mtimeit -s"from datetime import datetime;d={'2012-2-12':None, '2012-10-9':None, '1978-1-1':None, '1985-10-9':None}" 'sorted(d,key=lambda x: [int(y) for y in x.split("-")])'
100000 loops, best of 3: 17.6 usec per loop

米吉尔森的 zfill str.split解决方案:

bburns@virgil:~$ python -mtimeit -s"from datetime import datetime;d={'2012-2-12':None, '2012-10-9':None, '1978-1-1':None, '1985-10-9':None}" 'sorted(d,key=lambda x: [y.zfill(2) for y in x.split("-")])'
100000 loops, best of 3: 7.4 usec per loop

看来他是对的! mgilson 的原始答案快了 4-5 倍,他的最终答案快了 10-11 倍!然而,正如我们在评论中同意的那样,可读性很重要。除非您目前受 CPU 限制,否则我仍然建议您使用datetime.strptimeover str.split

于 2012-10-10T14:00:30.447 回答