在迭代列表时删除列表元素绝不是一个好主意。执行此操作的适当方法是将 acollections.Counter
与列表理解一起使用:
>>> from collections import Counter
>>> d = [1, 2, 1, 2, 4, 4, 5, 'a', 'b', 'a', 'b', 'c', 6, 'f', 3]
>>> # Use items() instead of iteritems() in Python 3
>>> [k for (k,v) in Counter(d).iteritems() if v > 1]
['a', 1, 2, 'b', 4]
如果您想按照它们在列表中出现的顺序保留重复元素:
>>> keep = {k for (k,v) in Counter(d).iteritems() if v > 1}
>>> [x for x in d if x in keep]
[1, 2, 1, 2, 4, 4, 'a', 'b', 'a', 'b']
我将尝试解释为什么您的方法不起作用。要了解为什么某些元素没有按应有的方式删除,假设我们想在循环遍历列表时b
从列表中删除所有 s 。[a, b, b, c]
它看起来像这样:
+------------------------+
| 一个 | 乙 | 乙 | c |
+------------------------+
^(第一次迭代)
+------------------------+
| 一个 | 乙 | 乙 | c |
+------------------------+
^(下一次迭代:我们找到了一个“b”——删除它)
+------------------------+
| 一个 | | 乙 | c |
+------------------------+
^(删除 b)
+-----------------+
| 一个 | 乙 | c |
+-----------------+
^(将后续元素向下移动以填补空缺)
+-----------------+
| 一个 | 乙 | c |
+-----------------+
^(下一次迭代)
请注意,我们跳过了第二个b
!一旦我们删除了第一个b
,元素就会向下移动,for
因此我们的 -loop 无法触及列表的每个元素。同样的事情也发生在您的代码中。