我有一个需要分配给时间窗口(7、9、12、15、18)的时间列表,以确保每个时间窗口都由列表中的元素覆盖。
from datetime import date, time, datetime
def nearest(items, target):
return min(items, key=lambda x: abs(x - target))
time_list = [datetime.datetime(2019, 12, 17, 7, 30),
datetime.datetime(2019, 12, 17, 9, 0),
datetime.datetime(2019, 12, 17, 16, 0),
datetime.datetime(2019, 12, 17, 18, 30),
datetime.datetime(2019, 12, 17, 21, 30),
datetime.datetime(2019, 12, 17, 12, 30),
datetime.datetime(2019, 12, 17, 19, 0),
datetime.datetime(2019, 12, 17, 0, 0),
datetime.datetime(2019, 12, 17, 14, 30)]
target_times = [datetime.combine(date.today(),time(i,0)) for i in range(6,19,3)]
coverage = [abs(nearest(time_list, t)-t)<time(1,30) for t in target_times]
所需的输出:
[True, True, True, True, True]
当前返回一个“
这是我根据此SO问题How to check if the current time is in range in python?组合而成的解决方案。它可以工作,但我想知道是否有更好的解决方案。
def time_in_range(start, end, x):
today = timezone.localtime().date()
start = timezone.make_aware(datetime.combine(today, start))
end = timezone.make_aware(datetime.combine(today, end))
x = timezone.make_aware(datetime.combine(today, x))
if end <= start:
end += timedelta(days=1) # tomorrow!
if x <= start:
x += timedelta(days=1) # tomorrow!
return start <= x <= end
downloaded = [False, False, False, False, False]
times = [time(i,0) for i in [5,8,10,13,16,20]]
for i in range(5):
for start_time in start_times:
if time_in_range(times[i], times[i+1], start_time):
downloaded[i] = True
您的直接问题的答案是,您正在尝试将timedelta
ob对象与time
对象进行比较。在这种情况下,您将想要创建一个timedelta
对象,如下所示:
timedelta(hours=1, minutes=30)
代替
time(1,30)
您可能希望在此处使用pandas;因为它具有处理垃圾箱和区间的内置方法。
在这种情况下,您有四(4)个时间间隔:
[“表示包容性,而”)“表示排除性。
您可以将time_list
加载到熊猫数据框中:
import pandas as pd
df = pd.DataFrame(time_list,columns=['timestamp']) # `columns` is how you name the column(s)
然后,我建议使用熊猫的原因是它具有一个有用的功能,称为.cut()
,可以对值进行分箱。
.cut()
然后您可以像这样测试上述操作的结果的适当长度(1的减法是因为有五个容器:
>>> bins = [7, 9, 12, 15, 18]
>>> pd.cut(df['timestamp'].dt.hour,bins=bins).unique().dropna().sort_values()
[(7, 9], (9, 12], (12, 15], (15, 18]]
如果您想要布尔值列表,则可以执行:
>>> covered_intervals = _ # an underscore gets the most recent value in the interpreter
>>> len(covered_intervals) == len(bins) - 1
True