Python list.remove()跳过列表中的下一个元素

Python list.remove()跳过列表中的下一个元素,python,Python,Python,但不是编程,这里是新手。我正在用列表编程,遇到了一个有趣的问题 width = 2 height = 2 # Traverse the board def traverse(x, y): # The four possible directions squares = [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)] print squares # Remove impossible squares

Python,但不是编程,这里是新手。我正在用列表编程,遇到了一个有趣的问题

width = 2
height = 2

# Traverse the board
def traverse(x, y):
    # The four possible directions
    squares = [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)]
    print squares

    # Remove impossible squares
    for square in squares:
        print "now accessing", square
        if (square[0] < 1 or square[0] > width or 
            square[1] < 1 or square[1] > height or
            square == (1, height)):
            squares.remove(square)
            print "removed", square
    print(squares)

# Testing traverse
traverse(1,1)

它完全跳过元素(2,1)和(1,2)——甚至不检查它们!我在这里找到的答案是,我不应该在遍历列表时修改它,是的,这绝对是有道理的。新手犯的错误。但是有人能告诉我为什么它不起作用吗?Python列表的面纱背后隐藏着什么?

在对列表进行迭代时,您正在从列表中删除它。这不是个好主意。

还有其他方法可以完成您正在尝试的操作,其中一种方法是跟踪要从列表中删除的所有项目的列表索引,然后将它们从for循环之外删除对于正方形中的正方形,语句
只需按顺序访问列表中的每个项目:
正方形[0]
,然后
正方形[1]
,然后
方块[2]
,依此类推,直到方块用完为止


删除
方块[0]
将列表中的所有其他项目向左移动一个插槽;原来的
squares[1]
现在是
squares[0]
,因此for循环将跳过它。

在Python中访问列表并删除元素时,列表会变短。 简单示例:以列表1、2、3、4、5为例,删除大于1的素数。
如果您查看第二个元素(2)并决定将其删除,那么最终将得到一个1,3,4,5的列表 现在你看第三个元素(你已经看了第二个),你会发现它是4。这不是素数,所以你转到第五个元素-5。将其移除。
结果:你有1,3,4,5。 如果您是从阵列的另一端开始的,那么一切都会正常工作。 有道理吗

编辑:
我在下面创建了另一个答案-其他海报对这个问题的解释比我在这里给出的更好,但我认为我有一个更优雅的解决方案。

不要修改您正在迭代的列表

相反,请执行以下操作:

for square in squares[:]:

因此,您在迭代列表副本的同时仍在更改原始列表。

其他人解释说,您不应该从正在迭代的数组中删除元素;但是,如果向后遍历数组,则没有问题

解决此问题最简单的方法(假设完成后不需要原始数组的副本)是使用
reversed()
函数,如中所示

用于倒方格(正方形)


这将从数组的末尾开始迭代,并向后运行。以这种方式取出元素不会影响代码的其余部分,因为您不会更改尚未访问的元素的顺序。我认为这是解决这个问题最优雅的方法。我学会了这个技巧

删除for循环中的数组元素是不可取的,因为for循环按顺序检查索引,删除循环中的元素会将进行中的元素左移一个索引,如果要这样做,请使用reversed()

arr=[1,2,3,4,5]

对于反向(arr)中的ele: 条件:
arr.remove(ele)

我假设Python在内部跟踪列表中的序号位置,并且删除一个项目会将该位置向下移动一个。我很惊讶这样做会奏效。我可以发誓,在迭代iterable时更改它会引发异常。我认为您遇到的问题与本SO问题中所述的问题相同:@sr2222对于某些类型,例如
dict
,确实如此(尽管我认为这只是一种可能失败的启发式方法)。在不慢到爬行的情况下检测到这一点是相当困难的。@sr2222:在迭代过程中,偶尔会出现
设置更改大小
错误;同样地,使用
dict
s和
deque
s。也许你就是这么想的,这绝对有道理。我本该看到的东西。:)谢谢你的快速回复!为了解决这个问题,我没有从这个列表中删除,而是将我想要保留的添加到一个新列表中。问题解决了!
for square in squares[:]: