循环的奇怪'部分完成'

时间:2014-08-10 15:44:27

标签: python loops for-loop

好吧这可能真的很微不足道(我对此很陌生),但我已经坚持了一段时间,我不明白为什么我的函数会返回如此奇怪的结果。

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)仍然在列表中。这几乎是不合逻辑的,请协助。

3 个答案:

答案 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)])