【问题标题】:TypeError: unsupported operand type(s) for -: 'datetime.time' and 'datetime.timedelta'TypeError: 不支持的操作数类型 -: 'datetime.time' 和 'datetime.timedelta'
【发布时间】:2021-05-22 01:42:42
【问题描述】:

Python datetime 不允许从 time 中减去 timedelta;我想这是因为timedelta 可以跨越数天,而time 仅在 24 小时内 (hh:mm:ss.ns)。

现在的问题是,是否有类似于timedelta 的数据结构允许直接从time 中进行减法运算?

我知道我可以将我的 datetime.time 转换为 datetime.timedelta 以启用另一个 datetime.timedelta 的减法。 但是我试图避免将time 转换为timedelta,因为我正在从一个大文件中读取时间,并且每次转换为 timedelta 的成本都很高。 但是,只需将timedelta 替换为some_datastructure(如果存在)并直接从time 中减去,这是一次性操作。

示例:

t1 = datetime.time(hour=1, minute=1, second=1)
# t1 = datetime.timedelta(hours=t1.hour, minutes=t1.minute, seconds=t1.second)
t_diff = datetime.timedelta(hours=0, minutes=0, seconds=1)
print(t1-t_diff)

**附言我用了多少time这个词time?!

【问题讨论】:

  • 您在大文件中的所有时间到底想做什么?另外,文件中每次的格式是什么? (例如 2 月 7 日晚上 9:30)
  • datetime.time 条目是从 pickle 文件加载的。前任。 datetime.time(1, 5, 52, 582000).
  • 至于我对条目所做的事情,我通过加/减 n 秒来扩展它们的跨度。然后使用结果来查找/比较 OrderedDict 中的值和 datetime.time 键。
  • 我们在谈论什么尺寸?我的意思是,元素的数量、重复次数等?
  • 好的,那么我肯定会尝试使用比 datetime.time 更简单的东西 - 自午夜以来的整数秒可能是一种选择,可能还有更多。

标签: python datetime


【解决方案1】:

转换为datetime.datetime 而不是datetime.timedelta 会更有效:

from random import randrange
from datetime import datetime, time, timedelta

# some random times:
N = int(1e6)
ts = [time(randrange(23),randrange(59),randrange(59),randrange(999999)) for _ in range(N)]

# to timedelta could look like
td = [timedelta(0, 0, (t.hour*60*60*1e6+t.minute*60*1e6+t.second*1e6+t.microsecond)) for t in ts]

# %timeit [timedelta(0, 0, (t.hour*60*60*1e6+t.minute*60*1e6+t.second*1e6+t.microsecond)) for t in ts]
# 856 ms ± 903 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

# to datetime could look like
today = datetime.now().date()
dt = [datetime.combine(today, t) for t in ts]

# %timeit [datetime.combine(today, t) for t in ts]
# 201 ms ± 1.85 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# now you'd do something with dt
ts_new = [(d + timedelta(seconds=5)).time() for d in dt]

# %timeit [(d + timedelta(seconds=5)).time() for d in dt]
# 586 ms ± 1.68 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

但仍然 - 对于 1M 元素示例,timeits 表明我们肯定落入了关键的>1ms 范围。如果你想走得更快,我想你必须首先使用另一种时间格式,例如从午夜开始的整数(微)秒。

【讨论】:

    猜你喜欢
    • 2015-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多