我有以下python代码对列表排序函数进行日期比较(例如date_list.sort(cmp=dcmp)
。我想知道是否可能删除cmp / if测试并使其成为oneliner。< / p>
def dcmp(a, b):
amm, add, ayy = [int(v) for v in a.split('/')]
bmm, bdd, byy = [int(v) for v in b.split('/')]
v = cmp(ayy, byy)
if v != 0: return v
v = cmp(amm, bmm)
if v != 0: return v
return cmp(add, bdd)
更新:让我说清楚我很好奇的是你可以从函数中删除这段代码:
v = cmp(ayy, byy)
if v != 0: return v
v = cmp(amm, bmm)
if v != 0: return v
return cmp(add, bdd)
答案 0 :(得分:2)
您可以使用key
代替cmp
。编写key
函数要容易得多,可以在一行中完成。
date_list.sort(key = lambda s: datetime.strptime(s, '%m/%d/%Y'))
您还需要此导入:
from datetime import datetime
答案 1 :(得分:0)
将这些值转换为实际日期肯定更清晰(尽管可能更慢 - 如果速度非常重要,您必须对其进行基准测试):
def dcmp(a, b):
from datetime.datetime import strptime
return strptime(a,'%m/%d/%Y') > strptime(b,'%m/%d/%Y')
答案 2 :(得分:0)
如果您的所有月份和日期都是零填充且日期为m / d / Y格式,例如“01/01/2001”,您可以写道:
def datekey(d):
m, d, y = d.split('/')
return (y, m, d)
datelist.sort(key=datekey)
如果数字并非总是填充零,您可以将每个数字转换为int以进行比较:
def datekey(d):
m, d, y = d.split('/')
return (int(y), int(m), int(d))
datelist.sort(key=datekey)
如果所有日期都采用如此简单的格式,则方式比使用strptime
更快:
>>> import timeit
>>> print timeit.Timer("datelist.sort(key=datekey)",
... setup="""\
... datelist = ['01/01/2001', '01/02/2001', '12/31/1999']
... def datekey(d):
... m, d, y = d.split('/')
... return (y, m, d)
... """).timeit()
3.3154168129
>>> print timeit.Timer("datelist.sort(key=datekey)",
... setup="""\
... datelist = ['01/01/2001', '01/02/2001', '12/31/1999']
... def datekey(d):
... m, d, y = d.split('/')
... return (int(y), int(m), int(d))
... """).timeit()
11.1701700687
>>> print timeit.Timer("datelist.sort(key = lambda s: datetime.datetime.strptime(s, '%m/%d/%Y'))",
... setup="""\
... datelist = ['01/01/2001', '01/02/2001', '12/31/1999']
... import datetime
... """).timeit()
59.2817358971
strptime
非常强大,非常重要,在这个用例中非常慢。
答案 3 :(得分:0)
想出来,我正在寻找的只是替换这段代码(忽略它是日期)
v = cmp(ayy, byy)
if v != 0: return v
v = cmp(amm, bmm)
if v != 0: return v
return cmp(add, bdd)
正确答案是:
return cmp(ayy, byy) or cmp(amm, bmm) or cmp(add, bdd)
也可以写成:
return cmp((ayy,amm,add), (byy,bmm,bdd))
答案 4 :(得分:-1)
忘记日期转换,您可以将其作为字符串执行。只需将它们重新排列到正确的顺序即可。
amm, add, ayy = a.split('/')
bmm, bdd, byy = b.split('/')
return cmp(ayy+amm+add, byy+bmm+bdd)
我更喜欢使用ISO date format,它将事情按照正确的顺序进行比较:YYYY-MM-DD
。它的优点是不会在海洋的另一边被误解。