Python如何按列表序列规则提取另一列表的对应元组范围
输入数据
给出两个列表如下:
l1 = [0,1,2,2,0,1,1,0] l2 = [(0,2),(3,5),(6,8),(9,10),(11,15),(16,18),(19,20),(21,22)]
需求规则
- 从
l1中找出所有仅由1和2组成的连续序列,且该序列之后紧跟的元素为1或0 - 返回结果为
l2中对应区间的元组:取序列起始索引对应l2元组的第一个元素,序列末尾索引对应l2元组的第二个元素,组成新的元组加入结果集 - 单个1后接0或1的场景也符合上述规则
预期输出结果:
out = [(3,10),(16,18),(19,20)]
现有代码问题说明
原有代码没有完整识别连续的1/2序列,每遍历到一个元素就直接拼接输出,导致把长序列拆成了多个短区间,才会出现多余的(3, 8)、(6, 10)、(9, 10)这类错误结果。
正确Python风格实现
核心思路是先遍历l1标记所有符合要求的连续1/2序列的起止索引,再去l2映射对应值即可:
l1 = [0,1,2,2,0,1,1,0] l2 = [(0,2),(3,5),(6,8),(9,10),(11,15),(16,18),(19,20),(21,22)] res = [] n = len(l1) start = None for i in range(n): # 匹配序列起点:当前值是1/2,且之前没有记录起点 if l1[i] in (1,2) and start is None: start = i # 匹配序列终点:已经记录起点,且触发结束条件 elif start is not None: # 结束条件:当前值为0,或者当前值为1且下一个值不是2,或者已经到列表末尾 if l1[i] == 0 or (l1[i] == 1 and (i == n-1 or l1[i+1] != 2)): end = i-1 if l1[i] == 0 else i res.append((l2[start][0], l2[end][1])) start = None # 处理边界:如果列表末尾刚好是1/2序列的情况 if start is not None: res.append((l2[start][0], l2[-1][1])) print(res)
运行后输出和预期完全一致:[(3, 10), (16, 18), (19, 20)]
内容的提问来源于stack exchange,提问作者Paschalis
相关产品推荐
相关产品推荐

