我刚开始用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]
最后一点我在其他地方找到了,但我似乎无法让它发挥作用。
任何帮助将不胜感激!
答案 0 :(得分: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))
答案 1 :(得分:1)
由于您没有发布错误消息,因此基于您的帖子的代码,存在一些问题
1)tmsg = examples.strftime('%d%b%Y')
无法正常工作,因为您在列表
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
答案 2 :(得分: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]
现在takewhile
会产生高达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
的列表,因为您实际上并不需要列表来处理您需要迭代一次的任何内容。如果要保留它以供检查或重复使用,请将parens更改为方括号。
另外,我将<
更改为<=
,因为您说“现在不是”,而不是“早于现在”(换句话说,现在应该计算)。< / p>
作为旁注,因为您碰巧有ISO-esque时间戳,实际上可以将它们排序为字符串:
>>> 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'
之前进行比较),但它不是'实际上你的原始代码存在问题。