好吧这可能真的很微不足道(我对此很陌生),但我已经坚持了一段时间,我不明白为什么我的函数会返回如此奇怪的结果。
testx = [(1,2), (1,1), (2,2), (3,5), (4,4), (5,5)]
def test_loop(interval_set):
for item in interval_set:
if item[0] == item[1]:
interval_set.remove(item)
return interval_set
print test_loop(testx)
>>>[(1, 2), (2, 2), (3, 5), (5, 5)]
如果您注意到,只有重复集(1,1)和(4,4)被删除,而(2,2)和(5,5)仍然在列表中。这几乎是不合逻辑的,请协助。
答案 0 :(得分:4)
迭代集合(字典,列表,集合),同时从中删除内容很糟糕,因为您将删除项目,缩短集合并提前退出循环。
我建议做一个列表理解,像这样:
[item for item in testx if item[0] != item[1]]
获得您期望的结果。
您可以在此处阅读有关列表理解的文档https://docs.python.org/2/tutorial/datastructures.html#list-comprehensions
答案 1 :(得分:2)
在迭代同一列表时,不应从列表中删除项目。尝试迭代该列表的副本,如下所示:
testx = [(1,2), (1,1), (2,2), (3,5), (4,4), (5,5)]
def test_loop(interval_set):
for item in list(interval_set):
if item[0] == item[1]:
interval_set.remove(item)
return interval_set
print test_loop(testx)
输出:
[(1, 2), (3, 5)]
答案 2 :(得分:0)
只是添加一些说明,为什么修改你正在迭代的序列是一个坏主意。这是一个列表,箭头指示迭代器当前的位置:
v
[0, 1, 2, 3, 4, 5]
现在让我们说你删除了0
,发生的事情是列表向前移动所以它现在看起来像这样,记下迭代器的位置:
v
[1, 2, 3, 4, 5]
现在迭代器前进到下一个项目而没有评估/比较/任何1
:
v
[1, 2, 3, 4, 5]
现在,您的代码已在for
循环的第一行备份,它将在值2
上执行您的代码,但1
从未进行过评估。
使用列表推导通常是最好的方法,但是由于理解语法的限制,有时需要单独的函数。
def test_loop(interval_set):
return [item for item in interval_set if item[0] != item[1]]
如果您在数学意义上构建set
(无重复项),也可以作为未来的提示,您可以随时:
>>> interval_set = [(1,1), (1,1), (2,2), (3,5), (4,4), (4,4)]
>>> set(interval_set)
set([(1,1), (2,2), (3,5),(4,4)])