首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >迭代失当的特定行为

迭代失当的特定行为
EN

Stack Overflow用户
提问于 2013-01-26 02:19:34
回答 6查看 427关注 0票数 2

最近有人问我关于在迭代时更改列表的失礼之处。他们给出了以下场景(我现在用更好的例子更新了它)作为可能的用例,当行为可能是合乎需要的时候:

代码语言:javascript
运行
复制
>>> jersey_numbers = [4, 2, 3, 5, 1]  # list of places in a race
>>> for jersey_number in jersey_numbers:
        if jersey_number == 2:  # disqualify jersey number 2 for a false start
            t.remove(jersey_number)
>>> t
[4, 3, 5, 1]  # jersey number 3 is now in second place

这种行为是否足够规则,可以在这样的用例中使用?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2013-01-26 02:23:43

当您从列表中删除一个项目时,列表中的所有内容都会移动...

代码语言:javascript
运行
复制
[1, 2, 3, 4, 5]
#remove   ^
[1, 2, 3, 5]

如果您在迭代对象时执行此操作,并且您希望移除彼此相邻的项,则当您移除第一个项时,第二个项将移位以取代它的位置。for循环将继续递增列表中它从列表中拉取值的位置,这会导致它跳过跳过的值,以取代您删除的项。

这是一个reference --让我们都知道这是一个有充分记录的行为:)

票数 7
EN

Stack Overflow用户

发布于 2013-01-26 02:32:22

你应该使用的是:

代码语言:javascript
运行
复制
t = filter(None, t)  # or
t = [x for x in t if x]

或者如果你的情况实际上更复杂:

代码语言:javascript
运行
复制
t = filter(lambda x: x != something, t)  # or
t = [x for x in t if x != something]

顺便说一句,remove删除了第一个匹配的元素,不一定是你的x当前指向的元素,尽管在你的例子中,简单的行为是等效的。

发生的情况是,当您迭代列表时,您删除了元素,而迭代器不知道这一点,假设您的列表是[1,0,0,2]

  • 迭代器在1,没有变化,下一个
  • 迭代器在0,你删除了一些第一个代码,列表改变了大小,现在迭代器指向第二个零,next
  • iterator指向2,没有变化

< 0 >F2162>

实际上,您的第一个算法每隔一秒就删除一次零。

你的第二个算法不应该工作,如果你说它工作,也许你没有对它进行足够的测试。

票数 5
EN

Stack Overflow用户

发布于 2013-01-26 02:20:34

错误在于你在遍历列表的时候修改了它。这并不是您所期望的行为(当您删除当前元素时,下一个元素将被跳过)。

下面是如何做到这一点:

代码语言:javascript
运行
复制
In [18]: t = [5.0, 5.0, 5.0, 4.0, 0.0, 5.0, 0.0, 3.0, 5.0, 5.0, 0.0, 0.0, 4.0, 5.0, 0.0, 5.0, 4.0, 5.0, 3.0, 3.0, 5.0, 5.0, 5.0, 5.0]

In [19]: t[:] = [val for val in t if val != 0]
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14527966

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档