我想替换列表l1
中同样位于l2
的元素,并删除不在l2
中的元素。我不明白为什么以下解决方案不起作用:它返回
[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]
答案 0 :(得分:1)
使用一个集来存储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。
答案 1 :(得分:1)
Padraic的解决方案似乎是要走的路,但是你明白为什么你的问题存在,你正在修改你在执行del l1[i]
步骤时迭代的列表。这将改变循环的下一次迭代中的所有索引,这不可能达到你想要的效果。
答案 2 :(得分:1)
为什么它不起作用,因为您正在迭代并从同一列表中删除l1
在此wor = 'c'
i = 2
时考虑迭代。
在此迭代中,由于列表中不存在'c'
,您将从列表中删除
l1 = [33, 33, 'd']
,新列表。
现在enumerate
函数已经到了结束,因为i=2
之后没有更多的索引(因为删除了列表l1
的长度缩小了)
答案 3 :(得分:1)
添加一些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
的大小。这让一切都搞砸了。你不应该这样做。
答案 4 :(得分:0)
在您的代码中,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
一
B'/ P>
C
德尔
d
[33,33,'',33]
[' a',' b',' d',' f']