我有两个清单,
l1 = [1,2,3,4,5,6]
l2 = [3,2]
Run Code Online (Sandbox Code Playgroud)
我想要的是删除l2中的列表l1的元素,因为我做了类似的事情,
for x in l1:
if x in l2:
l1.remove(x)
Run Code Online (Sandbox Code Playgroud)
它给出了类似的输出
[1, 3, 4, 5, 6]
Run Code Online (Sandbox Code Playgroud)
但输出应该是这样的
[1, 4, 5, 6]
Run Code Online (Sandbox Code Playgroud)
任何人都可以阐明这一点.
这很容易解释.
考虑你拥有的第一个数组:
| 1 | 2 | 3 | 4 | 5 | 6 |
Run Code Online (Sandbox Code Playgroud)
现在你开始迭代了
| 1 | 2 | 3 | 4 | 5 | 6 |
^
Run Code Online (Sandbox Code Playgroud)
没有任何事情发生,迭代器增量
| 1 | 2 | 3 | 4 | 5 | 6 |
^
Run Code Online (Sandbox Code Playgroud)
2被删除
| 1 | 3 | 4 | 5 | 6 |
^
Run Code Online (Sandbox Code Playgroud)
迭代器增量
| 1 | 3 | 4 | 5 | 6 |
^
Run Code Online (Sandbox Code Playgroud)
瞧,3还在那里.
解决方案是迭代矢量的副本,例如
for x in l1[:]: <- slice on entire array
if x in l2:
l1.remove(x)
Run Code Online (Sandbox Code Playgroud)
或反向迭代:
for x in reversed(l1):
if x in l2:
l1.remove(x)
Run Code Online (Sandbox Code Playgroud)
其行为如下:
| 1 | 2 | 3 | 4 | 5 | 6 |
^
| 1 | 2 | 3 | 4 | 5 | 6 |
^
| 1 | 2 | 4 | 5 | 6 |
^
| 1 | 2 | 4 | 5 | 6 |
^
| 1 | 4 | 5 | 6 |
^
| 1 | 4 | 5 | 6 |
^
Run Code Online (Sandbox Code Playgroud)
为什么不让它变得更简单?l1如果我们只想删除以下元素,则无需实际迭代l2:
for item in l2:
while item in l1:
l1.remove(item)
Run Code Online (Sandbox Code Playgroud)
这为您提供了所需的输出......
此外,正如评论者指出的那样,如果我们有可能重复:
l1 = filter(lambda x: x not in l2, l1)
Run Code Online (Sandbox Code Playgroud)
..或使用列表推导的许多其他变体.