查找列表中的非唯一元素不起作用

Tan*_*her 6 python python-2.7

我想在列表中找到非唯一元素,但我无法弄清楚为什么在下面的代码部分中没有发生这种情况.

>>> d = [1, 2, 1, 2, 4, 4, 5, 'a', 'b', 'a', 'b', 'c', 6,'f',3]
>>> for i in d:
...     if d.count(i) == 1:
...             d.remove(i)
... 
>>> d
[1, 2, 1, 2, 4, 4, 'a', 'b', 'a', 'b', 6, 3]
Run Code Online (Sandbox Code Playgroud)

应该删除6和3.在哪里,如果我使用

d = [1, 2, 1, 2, 4, 4, 5, 'a', 'b', 'a', 'b', 'c']
Run Code Online (Sandbox Code Playgroud)

我得到了正确答案.请解释发生了什么,我很困惑!

我使用的是python 2.7.5.

ars*_*jii 21

在迭代它时删除列表的元素绝不是一个好主意.执行此操作的适当方法是使用a collections.Counterwith list comprehension:

>>> 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]
Run Code Online (Sandbox Code Playgroud)

如果您希望按照它们在列表中出现的顺序保留重复元素:

>>> 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']
Run Code Online (Sandbox Code Playgroud)

我会试着解释为什么你的方法不起作用.要理解为什么某些元素不会被删除,想象一下我们想要在循环它时b从列表中删除所有s [a, b, b, c].它看起来像这样:

+-----------------------+
|  a  |  b  |  b  |  c  |
+-----------------------+
   ^ (first iteration)

+-----------------------+
|  a  |  b  |  b  |  c  |
+-----------------------+
         ^ (next iteration: we found a 'b' -- remove it)

+-----------------------+
|  a  |     |  b  |  c  |
+-----------------------+
         ^ (removed b)

+-----------------+
|  a  |  b  |  c  |
+-----------------+
         ^ (shift subsequent elements down to fill vacancy)

+-----------------+
|  a  |  b  |  c  |
+-----------------+
               ^ (next iteration)

请注意,我们跳过了第二个b!一旦我们删除了第一个b元素,元素就会向下移动,因此我们的for-loop无法触及列表中的每个元素.你的代码中也会发生同样的事情.

  • 使用Python 3.5.3,建议的解决方案返回一个错误:`AttributeError:'Counter'对象没有属性'iteritems'.而不是`iteritems()`我使用`items()`对我来说很好. (3认同)