0

我刚开始用 Python 编程,并且有一些简单的问题(可能)。我想做的是比较一些时间戳以找到最接近的时间戳。

基本上我想要做的是让当前的曲目在收音机上播放,他们有一个提要显示接下来的 20 个左右,以及曲目开始的时间。我想得到现在正在播放的内容!

这是一个示例字符串数组:

examples = ['2012-12-10 02:06:45', '2012-12-10 02:02:43', '2012-12-10 01:58:53']

现在我想做的是比较最接近现在(但不是更晚)的时间,以查看当前播放的内容。

到目前为止,这是我的脚本:

import datetime, itertools, time
currentTimeMachine = datetime.datetime.now()
now = currentTimeMachine.strftime("%Y-%m-%d %H:%M:%S")

examples = ['2012-12-10 02:06:45', '2012-12-10 02:02:43', '2012-12-10 01:58:53']
tmsg = examples.strftime('%d%b%Y')


 print [x for x in itertools.takewhile( lambda t: now > datetime.datetime.strptime(t, "%Y-%m-%d %H:%M:%S"), examples )][-1]

最后一点我在其他地方捡到了,但我似乎无法让它工作。

任何帮助将不胜感激!

4

3 回答 3

1

用于datetime.datetime.strptime()将字符串转换为日期时间对象。

>>> import datetime
>>> examples = ['2012-12-10 02:06:45', '2012-12-10 02:02:43', '2012-12-10 01:58:53']
>>> parsed_datetimes = [datetime.datetime.strptime(e, "%Y-%m-%d %H:%M:%S") for e in examples]
>>> parsed_datetimes
[datetime.datetime(2012, 12, 10, 2, 6, 45), datetime.datetime(2012, 12, 10, 2, 2, 43), datetime.datetime(2012, 12, 10, 1, 58, 53)]

然后,这将获得与当前日期时间的最小差异日期时间,“最接近现在now

>>> now = datetime.datetime.now()
>>> min_time_diff, min_datetime = min((now - i, i) for i in parsed_datetimes)
>>> min_time_diff, min_datetime
(datetime.timedelta(0, 36265, 626000), datetime.datetime(2012, 12, 10, 2, 6, 45))
于 2012-12-10T01:56:57.873 回答
1

由于您没有发布错误消息,因此根据您发布的代码,存在一些问题

1)tmsg = examples.strftime('%d%b%Y')不起作用,因为您在 strftime 列表上应用了调用

2)正如其他人已经指出的那样,在您将字符串与日期时间进行比较时。

这将起作用:

>>> import datetime, itertools, time
>>> currentTimeMachine = datetime.datetime.now()
>>> print [x for x in itertools.takewhile( lambda t: currentTimeMachine  > datetime.datetime.strptime(t, "%Y-%m-%d %H:%M:%S"), examples )][-1]
2012-12-10 01:58:53
于 2012-12-10T02:00:40.757 回答
1

其他答案已修复您的错误,因此您的算法现在可以正常运行。

但是算法本身是错误的。你想在不过去的情况下获得最接近现在的东西。但是你写的是:

 [x for x in itertools.takewhile(pred, examples)][-1]

想想这意味着什么。首先,takewhile将返回示例,直到其中一个未通过谓词。然后你会拿最后一个成功的。因此,如果您的示例如下所示:

[now-3, now-10, now-5, now+3, now-9, now-1, now+9]

首先,takewhile将产生now-3, now-10, now-5然后停止,因为pred(now+3)返回 False。然后,你拿最后一个,now-5

如果您按升序对示例进行排序,这将起作用:

[now-10, now-9, now-5, now-3, now-1, now+3, now+9]

Nowtakewhile将产生直到 的所有东西now-1,所以它产生的最后一件事就是你想要的。

但是您最初问题中的示例是按降序排列的,并且在对 Anthony Kong 的回答的评论中,您添加了一些根本不按任何顺序排列的示例。因此,您显然不能依赖它们按排序顺序排列。因此,一种可能的解决方法是对它们进行排序:

>>> import datetime, itertools, time
>>> currentTimeMachine = datetime.datetime.now()
>>> print [x for x in itertools.takewhile(lambda t: currentTimeMachine  > datetime.datetime.strptime(t, "%Y-%m-%d %H:%M:%S"), sorted(examples))][-1]
2012-12-10 02:06:45

或者,为了使事情更具可读性,打破最后一行,并摆脱无关的列表理解:

>>> exampleDates = [datetime.datetime.strptime(t, "%Y-%m-%d %H:%M:%S") for t in examples]
>>> def beforeNow(t):
...     return currentTimeMachine > t
>>> print list(itertools.takewhile(beforeNow, sorted(exampleDates))[-1]

然而,这是一种愚蠢的做事方式。您真正想要的是不在现在之后的示例中的最大值。所以只要把那个英文句子翻译成代码:

>>> print max(x for x in exampleDates if x <= currentTimeMachine)

让我们把它们放在一起:

>>> examples = ['2012-12-10 02:06:45', '2012-12-10 02:02:43', '2012-12-10 01:58:53']
>>> exampleDates = (datetime.datetime.strptime(t, "%Y-%m-%d %H:%M:%S") for t in examples)
>>> currentTimeMachine = datetime.datetime.now()
>>> print max(t for t in exampleDates if t <= currentTimeMachine)
2012-12-10 02:06:45

我使用了生成器表达式而不是列表,exampleDates因为您实际上不需要列表来处理任何只需要迭代一次的东西。如果您想保留它以供检查或重复使用,请将括号更改为方括号。

另外,我将 更改<<=,因为您说“现在不晚”而不是“比现在早”(换句话说,现在应该算数)。

附带说明一下,因为您碰巧有 ISO 式时间戳,您实际上可以将它们排序为字符串:

>>> now = datetime.datetime.now()
>>> currentTimeMachine = datetime.datetime.strftime(now, "%Y-%m-%d %H:%M:%S")
>>> print max(t for t in examples if t <= currentTimeMachine)
2012-12-10 02:06:45

这样做没有充分的理由,并且当您获得格式略有不同的时间戳(例如,'2012-12-10 02:06:45'比较之前'2012-12-10Z01:06:45')时,它总是会导致您出现错误,但这实际上不是您的原始代码的问题。

于 2012-12-10T03:00:17.200 回答