【问题标题】:Why stop the loop after remove an element? [duplicate]为什么在删除元素后停止循环? [复制]
【发布时间】:2015-02-15 07:36:43
【问题描述】:

我有以下代码 sn-p。为什么循环不从列表points 中删除所有点,我对此感到非常困惑。我的意思是,所有点都在三角形中。

print "check whether",points,"are in triangle"
print "p=",points[0]," is in triangle=",isPointInTri(a,b,c,points[0])
print "p=",points[1]," is in triangle=",isPointInTri(a,b,c,points[1])

for p in points:
    if isPointInTri(a,b,c,p):
        points.remove(p)
    print "now, the following points are available", points
print points

这是输出:

check whether [(2, 1), (4, 1)] are in triangle
p= (2, 1)  is in triangle= True
p= (4, 1)  is in triangle= True
now, the following points are available [(4, 1)]
[(4, 1)]

有人有想法吗?

【问题讨论】:

  • 您正在从您正在迭代的列表中删除元素。
  • 这不是一个完整的例子。 abc 是什么? isPointInTri 是如何定义的?
  • stackoverflow.com/questions/1207406/… 也得到了很好的答案。
  • 你是对的,但知道a,b,cisPointInTri 并不重要。问题是循环。也许,我不应该在同一个列表的迭代过程中删除一个项目。
  • @Sam 但是拥有MCVE 又名SSCCE... 很重要

标签: python loops


【解决方案1】:

您正在修改您正在迭代的列表。你不应该这样做。原因是for 循环使用了一个叫做iterator 的东西,它基本上指向列表中的一个current 元素,并且在每次迭代中移动到下一个元素。当列表被修改时,迭代器不知道它。当您删除一个元素时,迭代器仍然指向“内存中的相同位置”,即使现在列表更短了。所以它在集合结束之后“认为”它已经通过了所有元素。

试试这个:

points = [p for p in points if not isPointInTri(a,b,c,p)]

为此还有一个内置的filter 函数:

 points = filter(lambda p: not isPointInTri(a,b,c,p), points)

此外,按字面意思使用代码的最简单解决方法是复制初始列表:

for p in points[:]:
    if isPointInTri(a,b,c,p):
        points.remove(p)
    print "now, the following points are available", points
print points

像这样使用的切片运算符 ([:]) 将复制 points

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-16
    • 1970-01-01
    • 2013-05-20
    • 1970-01-01
    • 1970-01-01
    • 2019-08-03
    • 2019-03-30
    • 2015-08-19
    相关资源
    最近更新 更多