简化日期比较

时间:2011-10-27 20:26:02

标签: python

我有以下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)

5 个答案:

答案 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。它的优点是不会在海洋的另一边被误解。