[英]Python 2.7.5 .count() being ignored?
我正在尝试为某人调试一些代码,并且遇到了一个很奇怪的情况。 该代码的目的是在给定列表中搜索重复项,然后返回没有重复项的列表。 (请注意,编写代码的人选择仅从列表中删除重复项,而我本人只是将每个值添加到新列表中。但是,我仍然对这种奇怪之处感到好奇。) 代码如下:
def remove_duplicates(duplicates):
duplicates_del = duplicates
for i in duplicates_del:
if duplicates_del.count(i) > 1:
duplicates_del.remove(i)
return duplicates_del
remove_duplicates([3, 3, 3, 3, 3, 3])
运行时,代码将返回[3, 3, 3]
,经过一些调试后,我发现代码可以正常工作,直到duplicates_del.count(i)
等于4。在下一轮,它将完全跳过for语句中的所有内容,然后直接转到return语句,得到我们得到的答案。
我了解到,将if语句更改为while duplicates_del.count(i) > 1:
将使代码完美运行。
我研究了调试器的代码,并了解到有一个断点类可以忽略计数。 if语句是否以某种方式触发了该断点,还是还有另一个原因导致代码无法使用if语句而不是while循环来完全运行?
发生这种情况的原因是,在删除项目时要遍历列表。 这通常会导致意外结果。 看一眼:
L = [1, 2, 3, 4, 5]
for item in L:
if item == 1 or item == 2 or item == 3:
L.remove(item)
print L
输出为:
[2, 4, 5]
请注意,从未删除2
。 如果在每个循环中打印item
,则会得到:
1
3
5
在python删除1
,列表的顺序将改变,而2
不一定是循环中的下一个项目(实际上3
是)。 注意如何也跳过4
。
为了避免这种行为,您必须遍历列表的副本。 可悲的是,您没有复制。 进行duplicates_del = duplicates
将使两个对象引用相同的标识,因此更改一个元素将更改另一个元素。
你应该做这个:
def remove_duplicates(duplicates):
for i in duplicates[:]: # Creates a copy of the list
if duplicates.count(i) > 1:
duplicates.remove(i)
return duplicates
您正在循环从列表中删除。
通常,这意味着被删除的项目之后的项目将被跳过。
在这种情况下, remove
每次都删除第一个匹配元素,因此整个列表都向下移动。 列表迭代器看不到列表已更改,因此增加到下一项。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.