如果元组在 Python 中包含两个相邻的“1”,如何从列表中删除元组?

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 等等。

我应该怎么做?

Kel*_*ndy 8

您可以构建邻居对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)


kay*_*ya3 5

您的方法合乎逻辑,但不幸的是在 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)并拒绝您不想要的元素。