遍历列表并删除重复元素时的循环问题
我想遍历一个列表,然后把那些出现超过一次的项目去掉,这样在用for循环打印的时候就不会重复打印了。
可是,有些只出现一次的项目似乎也受到了影响,我搞不清楚为什么。
任何建议都会非常感谢。
示例输出:
listy = [2,2,1,3,4,2,1,2,3,4,5]
for i in listy:
if listy.count(i)>1:
print i, listy.count(i)
while i in listy: listy.remove(i)
else:
print i, listy.count(i)
输出结果:
2 4
3 2
1 2
这样就完全忽略了4和5。
8 个回答
1
在我遇到的所有编程语言中,边遍历一个列表边修改它都是个坏主意。我建议:不要这么做。这里有一些更好的方法。
使用 set
来找出唯一出现的元素
source = [2,2,1,3,4,2,1,2,3,4,5]
for s in set(source):
print s
这样你就能得到:
>>> source = [2,2,1,3,4,2,1,2,3,4,5]
>>> for s in set(source):
... print s
...
1
2
3
4
5
如果你想要计数,使用 defaultdict
from collections import defaultdict
d = defaultdict(int)
source = [2,2,1,3,4,2,1,2,3,4,5]
for s in source:
d[s] += 1
for k, v in d.iteritems():
print k, v
你会得到这个:
>>> for k, v in d.iteritems():
... print k, v
...
1 2
2 4
3 2
4 2
5 1
如果你想要排序的结果,使用 sort
和 operator
import operator
for k, v in sorted(d.iteritems(), key=operator.itemgetter(1)):
print k, v
你会得到这个:
>>> import operator
>>> for k, v in sorted(d.iteritems(), key=operator.itemgetter(1)):
... print k, v
...
5 1
1 2
3 2
4 2
2 4
3
你遇到的问题是因为在遍历一个列表的时候,同时对这个列表进行了修改。
如果你不在乎输出的顺序,也不在乎数量的话,可以直接使用集合(set):
>>> listy = [2,2,1,3,4,2,1,2,3,4,5]
>>> print set(listy)
set([1, 2, 3, 4, 5])
如果你在乎数量,那就可以使用标准库中的 collections
模块里的 Counter
类:
>>> import collections
>>> collections.Counter(listy)
Counter({2: 4, 1: 2, 3: 2, 4: 2, 5: 1})
>>> c = collections.Counter(listy)
>>> for item in c.iteritems():
... print "%i has a count of %i" % item
...
1 has a count of 2
2 has a count of 4
3 has a count of 2
4 has a count of 2
5 has a count of 1
如果你既在乎顺序又在乎数量,那你就需要再建立一个新的列表:
>>> checked = []
>>> counts = []
>>> for item in listy:
>>> if item not in checked:
>>> checked.append(item)
>>> counts.append(listy.count(item))
>>> print zip(checked, counts)
... [(2, 4), (1, 2), (3, 2), (4, 2), (5, 1)]
当然,这种方法是效率最低的。
如果你不打算以后再使用数量信息,那就不需要 counts
这个列表:
listy = [2,2,1,3,4,2,1,2,3,4,5]
checked = set()
for item in listy:
# "continue early" looks better when there is lots of code for
# handling the other case
if item in checked:
continue
checked.add(item)
print item, listy.count(item)
5
在遍历一个列表的时候,不应该对这个列表进行修改。这样做可能会导致一些意想不到的问题。下面的代码应该可以正常工作:
listy = [2,2,1,3,4,2,1,2,3,4,5]
found = set()
for i in listy:
if not i in found:
print i, listy.count(i)
found.add(i)
运行后的结果是:
2 4
1 2
3 2
4 2
5 1