如何基于时间范围将嵌套列表中的日期替换为1、0.5或0?
问题解决方案
原始数据
a = ['2023-02-10T00:00:35Z2023-02-13T00:00:00Z', '2023-02-06T09:03:24Z2023-02-13T00:00:00Z', '2023-02-11T19:27:55Z2023-02-18T19:00:00Z', '2023-02-12T18:00:00Z2023-02-13T04:00:00Z', '2023-02-12T18:00:51Z2023-02-19T00:00:00Z', '2023-02-12T20:00:00Z2023-02-13T01:00:00Z'] b = [['2023-02-10', '2023-02-11', '2023-02-12'], ['2023-02-10', '2023-02-11', '2023-02-12'], ['X', '2023-02-11', '2023-02-12'], ['X', 'X', '2023-02-12'], ['X', 'X', '2023-02-12'], ['X', 'X', '2023-02-12']]
需求说明
两个列表长度相同,b的第n个子列表对应a的第n个时间范围元素,按位置一一对应处理:将b中的日期值按规则替换为1、0.5或0,'X'保持不变。
替换规则
规则:若指定日期的时长满24小时则替换为1;时长大于0且不足24小时则替换为0.5;时长为0则替换为0。
期望输出
b = [[1,1,1],[1,1,1],['X',0.5,1],['X','X',0.5],['X','X',0.5],['X','X',0.5]]
用户尝试的思路
for l in b: for i,x in enumerate(l): for k in a: if x == k.split('T')[0]: if k.split('T')[1][:2] != '00': ######
存在的问题:无法实现a和b的位置一一对应遍历,且缺少时间范围的完整时长计算逻辑。
解决方案
使用zip()实现a和b的并行遍历,结合datetime模块准确计算日期覆盖时长,代码如下:
import datetime a = ['2023-02-10T00:00:35Z2023-02-13T00:00:00Z', '2023-02-06T09:03:24Z2023-02-13T00:00:00Z', '2023-02-11T19:27:55Z2023-02-18T19:00:00Z', '2023-02-12T18:00:00Z2023-02-13T04:00:00Z', '2023-02-12T18:00:51Z2023-02-19T00:00:00Z', '2023-02-12T20:00:00Z2023-02-13T01:00:00Z'] b = [['2023-02-10', '2023-02-11', '2023-02-12'], ['2023-02-10', '2023-02-11', '2023-02-12'], ['X', '2023-02-11', '2023-02-12'], ['X', 'X', '2023-02-12'], ['X', 'X', '2023-02-12'], ['X', 'X', '2023-02-12']] # 遍历对应位置的时间范围和子列表 for time_range, sub_list in zip(a, b): # 拆分开始/结束时间(ISO格式时间固定20位长度) start_str = time_range[:20].replace('Z', '+00:00') end_str = time_range[20:].replace('Z', '+00:00') start = datetime.datetime.fromisoformat(start_str) end = datetime.datetime.fromisoformat(end_str) # 处理子列表中的每个元素 for idx, val in enumerate(sub_list): if val == 'X': continue # 构造当前日期的0点和23:59:59时间点 date_start = datetime.datetime.fromisoformat(f"{val}T00:00:00+00:00") date_end = datetime.datetime.fromisoformat(f"{val}T23:59:59+00:00") # 计算时间范围与当前日期的交集 overlap_start = max(start, date_start) overlap_end = min(end, date_end) # 计算交集时长 duration_sec = (overlap_end - overlap_start).total_seconds() if duration_sec <= 0: sub_list[idx] = 0 else: duration_hours = duration_sec / 3600 sub_list[idx] = 1 if duration_hours >= 24 else 0.5 print("b =", b)
关键逻辑说明
- 并行遍历:用
zip(a, b)直接将a的时间范围和b对应子列表配对,解决位置对应问题。 - 时间拆分:利用ISO时间固定20位长度的特性切片拆分,比字符串分割更可靠。
- 时长计算:通过
datetime计算时间范围与目标日期的交集,准确得到实际覆盖时长,再按规则替换值。
内容的提问来源于stack exchange,提问作者Jazz365
相关产品推荐
相关产品推荐

