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']
我想替换列表 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']