我无法为我的问题提出更好的标题,对不起。
我有两个相同长度的列表,例如
a = [True, False, False, True, True, False, False, True]
b = [1, 2, 2, 1, 1, 3, 3, 2 ]
i j i' j'
我希望调整列表a
,以便每当列表False
中有一个或a
块从索引i
转到{{ 1}},根据以下条件进行调整:
j
在上面的例子中有两个这样的块:if b[i-1]==b[j+1]:
a[i:j+1]=[True]*(j-i+1)
和i,j=1,2
。
结果应该是:
i',j'=5,6
我使用a = [True, True, True, True, True, False, False, True]
s编写了一个带有for
循环的解决方案,但由于我想在非常大的列表中使用它,因此速度太慢了。
if
非常感谢任何帮助。 (评论和变量名称就像它用于分析物理模拟一样)
答案 0 :(得分:1)
你可以试试这个:
import itertools
a = [True, False, False, True, True, False, False, True]
b = [1, 2, 2, 1, 1, 3, 3, 2 ]
new_a = [(a, list(b)) for a, b in itertools.groupby(zip(a, b), key=lambda x:x[0])]
final_list = list(itertools.chain(*[[True]*len(b) if not a and new_a[i-1][-1][-1] == new_a[i+1][-1][-1] and i > 0 else [c for c, d in b] for i, [a, b] in enumerate(new_a)]))
输出:
[True, True, True, True, True, False, False, True]
编辑:使用新输入进行测试:
a = [True, False, True]
b = [1, 3, 1]
new_a = [(a, list(b)) for a, b in itertools.groupby(zip(a, b), key=lambda x:x[0])]
final_list = list(itertools.chain(*[[True]*len(b) if not a and new_a[i-1][-1][-1] == new_a[i+1][-1][-1] and i > 0 else [c for c, d in b] for i, [a, b] in enumerate(new_a)]))
输出:
[True, True, True]
代码说明:
itertools.groupby
将True
/ False
值的连续块形成单个列表。然后,final_list
存储迭代new_a
中存储的列表的结果,如果子列表完全由True
值组成,则创建False
值的新子列表如果前面和后面的值相同。这是通过使用enumerate
来获取每次迭代的当前索引来确定的。然后,该索引可用于通过i-1
,i+1
访问上述和后续值。