Python list.remove()跳过列表中的下一个元素
Python,但不是编程,这里是新手。我正在用列表编程,遇到了一个有趣的问题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
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[:]: