首页 > 解决方案 > 基于另一个列表中的序列迭代和求和第二个列表的元素

问题描述

我有两个清单

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)]

如果第一个列表中有1和2的序列,后跟1或0,那么我希望它返回第二个列表中相应索引中的元组的第一个元素和最终的元组的第二个元素2. 如果只有 1 则相同,后跟 o 或 1。

所以这里的输出应该是

out = [(3,10),(16,18),(19,20)]

这就是我所拥有的

for index, item in enumerate(true):
    if item == 0:
        continue
    elif item == 1 or item == 2:
        if true[index+1] == 0 or true[index+1] == 1:
            out.append(offsets[index])
        elif true[index+1] == 2:
            out.append((offsets[index][0], offsets[index+1][1]))

这导致

[(3, 8), (6, 10), (9, 10), (16, 18), (19, 20)]

有没有更pythonic(和正确)的方法来解决这个问题?

标签: 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)]

# adding 0 handles the case where l1 doesn't end with 0
it = enumerate(l1+[0])

result = []

sv = 0
try:
    while True:
        if sv==1:
            fi,fv = si,sv
        else:
            while True:
                fi,fv = next(it)
                if fv:
                    break
        while True:
            si,sv = next(it)
            if sv == 0 or sv == 1:
                break
        result.append((l2[fi][0],l2[si-1][1]))
except StopIteration:
    pass

print(result)

输出:

[(3, 10), (16, 18), (19, 20)]

我选择通过从表达式中创建一个迭代器来手动迭代第一个列表enumerate(这已经可以了,因为enumerate它已经是一个迭代器了)。这样,我可以在第一个索引上手动迭代,然后在第二个索引上使用内部while True循环和next,找到时中断。

如果第二个值是 a 1,它会停止序列,但也需要在迭代中重新注入下一个第一个值。使用迭代器是不可能做到这一点的,因此要测试先前的svsi值以避免错过第三个序列。


推荐阅读