我正在尝试用Python编写一个程序:
当我在变量中写入时间戳时代码有效,但当我尝试将文件用作输入时没有任何反应。程序运行,但没有任何内容打印到控制台。
这是代码的外观:
import csv
import datetime
from Tkinter import Tk
from tkFileDialog import askopenfilename
Tk().withdraw()
toopen = askopenfilename(filetypes=[("Text file","*.txt")])
with open(toopen, 'rb') as f:
reader = csv.reader(f, delimiter='\t')
for row in reader:
code = row[0]
times = row[1].split()
times = [datetime.datetime.strptime(x, "%H:%M:%S.%f") for x in times]
for i in range(len(times) - 1):
delta = times[i + 1] - times[i]
print ((delta.days * 24 * 60 * 60 + delta.seconds) * 1000 + delta.microseconds / 1000)
以下是我输入文件外观的示例。
input23 13:13:05.674430
input47 13:13:06.623822
input52 13:13:07.573215
input66 13:13:08.522607
任何帮助都表示赞赏,因为我真的被困在这里! 感谢
答案 0 :(得分:1)
为什么要分割row[1]
返回的内容?这只是一个时间戳,你正在从中列出一个项目。
然后,在列表推导中,您使用一个时间戳迭代该列表,并从中列出一个 datetime
实例。< / p>
请注意,此时len(times)
为1.因此,在执行for i in range(len(times) - 1)
时,您实际上正在迭代range(0)
,这是一个空列表。
你真正想要的是让第二个for循环在第一个之外。或者甚至更好,用更简单的列表理解替换整个第一个for row in reader:
循环,如下所示:
reader = csv.reader(f, delimiter='\t')
times = [datetime.datetime.strptime(timestamp, "%H:%M:%S.%f") for _, timestamp in reader]
for i in range(len(times) - 1):
delta = times[i + 1] - times[i]
print ((delta.days * 24 * 60 * 60 + delta.seconds) * 1000 + delta.microseconds / 1000)
如果您愿意,可以通过替换for
和索引来改进剩余的range()
循环,方法是迭代一对datetime
实例及其后续版zip()
列表中的一个版本本身移动了一个位置,可以说它更具可读性和pythonic:
reader = csv.reader(f, delimiter='\t')
times = [datetime.datetime.strptime(timestamp, "%H:%M:%S.%f") for _, timestamp in reader]
for time1, time2 in zip(times, times[1:]):
delta = time2 - time1
print ((delta.days * 24 * 60 * 60 + delta.seconds) * 1000 + delta.microseconds / 1000)
正如J.F. Sebastian指出的那样,使用timedelta
而不是手动组合所有3个组件,您可以从total_seconds()
轻松获得总毫秒数。因为那已经返回了微秒分辨率的结果(它是一个浮点数),你只需要乘以1000即可得到毫秒。如果您想要或不介意小数部分,那么您就完成了,否则您需要round()
和/或转换为int()
:
print(delta.total_seconds() * 1000)
或
print(int(delta.total_seconds() * 1000))