Python 简化日期比较

Python 简化日期比较,python,Python,我有以下python代码为列表排序函数(例如,date\u list.sort(cmp=dcmp))执行日期比较。我想知道是否可能删除cmp/if测试并使其成为一个单行程序 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

我有以下python代码为列表排序函数(例如,
date\u list.sort(cmp=dcmp)
)执行日期比较。我想知道是否可能删除cmp/if测试并使其成为一个单行程序

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)

您可以使用
key
而不是
cmp
。编写
key
函数要容易得多,而且可以在一行中完成

date_list.sort(key = lambda s: datetime.strptime(s, '%m/%d/%Y'))
您还需要此导入:

from datetime import datetime

您可以使用
key
而不是
cmp
。编写
key
函数要容易得多,而且可以在一行中完成

date_list.sort(key = lambda s: datetime.strptime(s, '%m/%d/%Y'))
您还需要此导入:

from datetime import datetime

将这些值转换为实际日期当然更干净(尽管可能更慢——如果速度如此重要,您必须对其进行基准测试):


将这些值转换为实际日期当然更干净(尽管可能更慢——如果速度如此重要,您必须对其进行基准测试):


忘记日期转换吧,你可以把它当作字符串来做。只要把它们重新排列成正确的顺序就行了

amm, add, ayy = a.split('/')
bmm, bdd, byy = b.split('/')
return cmp(ayy+amm+add, byy+bmm+bdd)

我更喜欢使用将事物按正确的顺序进行比较:
YYYY-MM-DD
。它还有一个优点,就是不会在大洋彼岸被误解。

忘记日期转换,你可以将其作为字符串来做。只需将它们重新排列到正确的顺序即可

amm, add, ayy = a.split('/')
bmm, bdd, byy = b.split('/')
return cmp(ayy+amm+add, byy+bmm+bdd)

我更喜欢使用将事情按正确顺序进行比较的:
YYYY-MM-DD
。它还有一个优点,就是在大洋彼岸不会被误解。

如果你所有的月份和日期都是零填充的,日期都是m/d/Y格式,如“01/01/2001”,你可以这样写:

def datekey(d):
    m, d, y = d.split('/')
    return (y, m, d)

datelist.sort(key=datekey)
如果数字并非总是零填充的,则可以将每个数字转换为整数进行比较:

def datekey(d):
    m, d, y = d.split('/')
    return (int(y), int(m), int(d))

datelist.sort(key=datekey)
如果您的所有日期都采用如此简单的格式,那么这比使用strtime要快得多:

>>> 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

strtime
功能强大,非常重要,在这个用例中非常慢。

如果您所有的月份和日期都是零填充的,并且日期是m/d/Y格式,如“01/01/2001”,您可以写:

def datekey(d):
    m, d, y = d.split('/')
    return (y, m, d)

datelist.sort(key=datekey)
如果数字并非总是零填充的,则可以将每个数字转换为整数进行比较:

def datekey(d):
    m, d, y = d.split('/')
    return (int(y), int(m), int(d))

datelist.sort(key=datekey)
如果您的所有日期都采用如此简单的格式,那么这比使用strtime要快得多:

>>> 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

strtime
功能非常强大,非常重要,在这个用例中非常慢。

想出来了,我想要的只是替换这个代码(忽略它是日期

正确答案是:

return cmp(ayy, byy) or cmp(amm, bmm) or cmp(add, bdd)
也可以写为:

return cmp((ayy,amm,add), (byy,bmm,bdd))

我明白了,我要找的只是替换这段代码(忽略它是日期

正确答案是:

return cmp(ayy, byy) or cmp(amm, bmm) or cmp(add, bdd)
也可以写为:

return cmp((ayy,amm,add), (byy,bmm,bdd))


为什么要以参数字符串开头?Python有一种类型。因为它们是从文件中读取的,看起来像“10/12/2011”,并用作dict键。我仍然认为NullUserException有一点。您可以使用将这些字符串轻松地转换为datetime对象。这将允许您进行比较,并且仍然可以将它们用作dict键。您可以使用
date
对象也是键。为什么要以参数字符串开头?Python有一种类型。因为它们是从文件中读取的,看起来像“10/12/2011”,并用作dict键。我仍然认为NullUserException有一个要点。您可以轻松地使用将这些字符串转换为datetime对象。这将允许您进行比较,并且可以仍然使用它们作为dict键。你也可以使用
日期
对象作为键。更不用说使用
可能更有效。更不用说使用
可能更有效。-1与OP的代码不同,如果天数或月份没有前导零,这将失败。@JohnMachin,公平的批评。A我说过,我更喜欢使用保证前导零的格式。感谢你解释了否决票,我确实比匿名投票更欣赏它。大洋彼岸也是如此。经典失败:批处理作业拒绝新“另一边”提供的文件中约60%的出生日期和就业开始日期子公司。费力地“纠正”并重新输入拒绝。未实现(直到很久以后)还有大约37%可能被塞住了,但没有被检测到。-1与OP的代码不同,如果几天或几个月没有前导零,这将失败。@JohnMachin,公正的批评。正如我所说,我更喜欢使用前导零有保证的格式。感谢你解释否决票,我确实比匿名者更欣赏它s类。大洋彼岸也是如此。经典失败:批量作业拒绝新“另一边”子公司提供的文件中约60%的出生日期和就业开始日期。拒绝费力地“更正”并重新输入。没有实现(直到很久以后)还有大约37%可能被塞住了,但没有被检测到。-1个错误代码的基准是徒劳的。
datekey('12/31/1999')
products
[1999,31,12]
FAILAww,crud.Edited。不过,对失败毫无意义。-1个错误代码的基准是徒劳的。
datekey('12/31/1999')
products
[1999,31,12]
FAILAww,crud.Edited。不过,对于失败,做一个混蛋毫无意义。