Med*_*dve 1 python for-loop tuples
我有一个元组列表:
from itertools import product
l1 = list((product((0,1), repeat = n)))
Run Code Online (Sandbox Code Playgroud)
对于 n=4,输出如下:
[(0, 0, 0, 0),
(0, 0, 0, 1),
(0, 0, 1, 0),
(0, 0, 1, 1),
(0, 1, 0, 0),
(0, 1, 0, 1),
(0, 1, 1, 0),
(0, 1, 1, 1),
(1, 0, 0, 0),
(1, 0, 0, 1),
(1, 0, 1, 0),
(1, 0, 1, 1),
(1, 1, 0, 0),
(1, 1, 0, 1),
(1, 1, 1, 0),
(1, 1, 1, 1)]
Run Code Online (Sandbox Code Playgroud)
我想删除至少有两个“1”彼此相邻的元组,例如(0,1,1,0).
我试过这个:
for i in l1:
for j in i:
if j==1 and j+1 == 1:
l1.remove(i)
Run Code Online (Sandbox Code Playgroud)
我想这是行不通的,因为它需要 j+1 作为实际数字 + 1,就像如果 j=1 它需要 2 等等。
我应该怎么做?
您可以构建邻居对zip(i, i[1:])并检查它们是否包含(1, 1):
>>> [i for i in l1 if (1, 1) not in zip(i, i[1:])]
[(0, 0, 0, 0), (0, 0, 0, 1), (0, 0, 1, 0), (0, 1, 0, 0),
(0, 1, 0, 1), (1, 0, 0, 0), (1, 0, 0, 1), (1, 0, 1, 0)]
Run Code Online (Sandbox Code Playgroud)
您的方法合乎逻辑,但不幸的是在 Python(或大多数其他语言)中不起作用,并且实现不正确,因为j==1 and j+1 == 1永远不会正确;如果j等于 1 那么j+1等于 2,周期。但更大的问题是您试图在迭代列表时从列表中删除内容,这是一个禁忌。
首先让我们解决如何检查两个1是否彼此相邻的问题。而不是查看jand j+1,我们需要查看t[j]和t[j+1]wheret是元组之一。此外,j需要迭代到长度减 1,否则t[j+1]将IndexError在元组的末尾给出一个。该any函数是执行此操作的便捷方法:
any(t[j] == t[j+1] == 1 for j in range(n - 1))
Run Code Online (Sandbox Code Playgroud)
请注意,t[j] == t[j+1] == 1由于链式比较,它在 Python 中有效。
现在让我们解决如何从列表中删除这些元素的问题。简单地用您想要的元素构建一个新列表要方便得多,而不是删除您不想要的元素。列表推导式是一种方便的方法:
result = [
t for t in product((0, 1), repeat=n)
if not any(t[j] == t[j+1] == 1 for j in range(n - 1))
]
Run Code Online (Sandbox Code Playgroud)
结果:
[(0, 0, 0, 0),
(0, 0, 0, 1),
(0, 0, 1, 0),
(0, 1, 0, 0),
(0, 1, 0, 1),
(1, 0, 0, 0),
(1, 0, 0, 1),
(1, 0, 1, 0)]
Run Code Online (Sandbox Code Playgroud)
综上所述,对于较大的 n,使用仅生成您想要的元素的算法会更有效,而不是遍历整个笛卡尔积(大小为 2 n)并拒绝您不想要的元素。