Python 替换一个列表中也在另一个列表中的元素,并删除其他元素

Python Replace elements in a list that are also in another list, and delete others

我想替换列表 l1 中也在 l2 中的元素,并删除不在 l2 中的元素。我不明白为什么以下解决方案不起作用:它 returns

[33, 33, 'd']

而不是:

[33, 33, '33'] 

这是我的解决方案:

l1=['a','b','c', 'd']
l2= ['a','b','d','f']
for (i,wor) in enumerate(l1):
    if wor in l2:
        l1[i]= 33
    else:
        del l1[i]

使用集合存储l2个元素,只需将集合中的元素替换为33:

l1=['a','b','c', 'd']
l2= ['a','b','d','f']
st = set(l2)
l1[:] = [33 for ele in l1 if ele in st]
print(l1)

您的代码无法正常工作,因为您正在从迭代列表中删除元素。当您 del l[i] 更改了列表的大小时,因此 l[i] 最初与您删除元素后 l[i] 指向的内容不同。您永远不应该从您正在迭代的列表中删除元素,或者正如您从输出中看到的那样,错误的元素最终可能会被删除。

如果您从原始列表开始:

l1=['a','b','c', 'd']
index  0 == a
index 1 == b
index 2 == c
index 3 == d

然后,如果您删除 c,则 d 位于索引 2,因此您最终会丢失 d.

您只需要在删除前后添加打印:

for (i, wor) in enumerate(l1):
    if wor in l2:
        l1[i] = 33
    else:
        print(l1[i],l1)
        del l1[i]
        print(l1[i],l1)

c [33, 33, 'c', 'd']
d [33, 33, 'd']

如果你把g加到l1你会看到一个更明显的错误:

l1=['a','b', "c", 'd',"g"]
l2= ['a','b','d','f'] 

for (i, wor) in enumerate(l1):
    if wor in l2:
        l1[i] = 33
    else:
        print(l1[i],l1)
        del l1[i]
        print(l1[i],l1)
print(l1)

c [33, 33, 'c', 'd', 'g']
d [33, 33, 'd', 'g']
g [33, 33, 'd', 'g']
Traceback (most recent call last):
  File 
  ..........
    print(l1[i],l1)
IndexError: list index out of range

因为您更改了大小,所以不再有 l[4]。您的代码并没有出错,只是因为 l1 的最后一个元素恰好在 l2 中。

Padraic 的解决方案似乎是可行的方法,但是为了让您了解为什么您的解决方案有问题,您正在修改您在执行 del l1[i] 步骤时迭代的列表。这将在循环的下一次迭代中更改所有索引,这不太可能按照您的意愿进行。

为什么它不起作用,因为您正在从同一个列表中迭代和删除,l1

这里考虑 wor = 'c' 时的迭代 i = 2

在此迭代中,由于 'c' 不在列表中,您将从

所在的列表中删除

l1 = [33, 33, 'd'],新榜单。

现在 enumerate 函数已经结束,因为在 i=2 之后没有更多的索引(因为列表的长度 l1 由于删除而缩小了)

添加一些 print 调用以查看会发生什么:

l1=['a','b','c', 'd']
l2= ['a','b','d','f']
for (i,wor) in enumerate(l1):
    if wor in l2:
        l1[i]= 33
    else:
        del l1[i]
    print(i, len(l1)) 

打印:

0 4
1 4
2 3

索引按照原来的 l1 继续运行,但您在迭代期间更改了 l1 的大小。这把一切都搞砸了。你不应该这样做。

在您的代码中,build_in 函数 del 删除了该列表中的特定值。因此列表的当前大小减少了一个 3。因此循环结束。

下面是区分方法的示例代码:

l1=['a','b','c','d']
l2= ['a','b','d','f']    
i=0
for wor in l1:
    print wor
    if wor in l2:
        print 'id'
        l1[i]= 33
    else:
        #del l1[i]
        l1[i]=''
        print 'del'
    i+=1


print l1
print l2

a

b

c

del

d

[33, 33, '', 33]

['a', 'b', 'd', 'f']