使用 for 循环 [duplicate] 删除特定元素

removing an specific element using for loop [duplicate]

提问人:Sartaj Ansari 提问时间:8/6/2023 更新时间:8/6/2023 访问量:44

问:

当我看到循环能够迭代时,我试图从列表中删除最小值,但它并没有删除最小值的每次出现。在本例中,它是 -51。

marks = [-50, -50, -50 ,51]
to_pop  = -50
for i in marks:
    if i == to_pop:
        marks.remove(to_pop)

    print(f"printing list {marks} after removing {to_pop}")
~                                                              

我试图使用 printf 找出我的代码有什么问题,但找不到为什么列表始终保持为 [-50, 51]。 我可以解决的是使用 while 循环

while to_pop in marks:
    marks.remove(to_pop)

但我想了解问题所在

python 列表 for-loop while 循环

评论


答:

1赞 Sash Sinha 8/6/2023 #1

问题在于,您正在尝试修改列表(通过删除元素),同时对其进行迭代。这通常不会像您在 Python 中预期的那样运行。

从列表中删除项目时,该列表将重新编制索引。循环不知道这一点,并将继续迭代原始索引。

使用示例列表:[-50, -50, -50, 51]

  1. 在第一次循环迭代中,是第一个 .循环的“内部计数器”现在为 0(第一项的索引)。然后,删除第一个 .列表现在是 .i-50-50[-50, -50, 51]

  2. 在第二次迭代中,循环的“内部计数器”变为 1(它认为它位于第二项),但由于我们删除第一项时重新编制索引,它正在查看原始列表中的第三项(现在是当前列表中的第二项)。它完全跳过了第二个。-50

  3. 在第三次迭代中,循环的“内部计数器”变为 2,但列表现在只有三个项目长,因此循环结束。

这就是为什么您会看到并非所有 s 都被删除的原因。使用循环是解决此问题的好办法。它会检查是否在列表中,将其删除,然后从列表的开头再次检查,因此它不会有同样的问题。-50while-50

如果你想坚持一个循环,你可以创建一个新列表,只包含你要保留的项目:for

marks = [-50, -50, -50, 51]
to_pop = -50
marks = [i for i in marks if i != to_pop]
print(marks)  # [51]

这种列表推导基本上与循环所做的事情相同,但以一种更 Python 和更有效的方式,因为它不会每次都检查列表的每个元素(循环条件在内部使用 for 循环)。whilewhileto_pop in marksc

评论

0赞 user19077881 8/6/2023
理解是最清晰的方法。出于对 OP 的兴趣,避免 remove-whilst-iterating 问题的另一种方法是向后循环遍历 List,边走边删除,因为索引位置不会因删除而受到影响。