【问题标题】:how to correctly modify the iterator of a loop in python from within the loop如何从循环中正确修改python中循环的迭代器
【发布时间】:2012-01-22 14:14:19
【问题描述】:

我基本上需要的是检查列表的每个元素,如果符合某些条件,我想将其从列表中删除。

举个例子吧

list=['a','b','c','d','e']

我基本上想写(原则上而不是我尝试实现的实际代码)

如果列表中的元素是“b”或“c”,则将其从列表中删除并取下一个。

但是

for s in list:
    if s=='b' or s=='c':
        list.remove(s)

失败,因为当 'b' 被删除时,循环将 'd' 而不是 'c' 作为下一个元素。那么有没有办法比将元素存储在单独的列表中然后删除它们更快呢?

谢谢。

【问题讨论】:

    标签: python loops iterator


    【解决方案1】:

    更简单的方法是使用列表的副本 - 可以使用从列表“开始”延伸到“结束”的切片来完成,如下所示:

    for s in list[:]:
        if s=='b' or s=='c':
            list.remove(s)
    

    您已经考虑过这一点,并且这很简单,可以在您的代码中,除非这个列表真的很大,并且在代码的关键部分(例如,在动作游戏的主循环中)。在这种情况下,我有时会使用以下成语:

    to_remove = []
    for index, s in enumerate(list):
        if s == "b" or s == "c":
             to_remove.append(index)
    
    for index in reversed(to_remove):
        del list[index]
    

    当然你也可以使用 while 循环:

    index = 0
    while index < len(list):
       if s == "b" or s == "c":
           del list[index]
           continue
       index += 1
    

    【讨论】:

    • jsbueno 非常感谢。我为自己没有这么想而感到有些惭愧。再次感谢!
    • 我实际上想要一个循环内的循环,你的最后一个例子是完美的。再次感谢。
    【解决方案2】:

    最好不要重新发明已经可用的东西。在这些情况下使用 filter 函数和 lambda。它更pythonic,看起来更干净。

    filter(lambda x:x not in ['b','c'],['a','b','c','d','e'])
    

    您也可以使用列表推导

    [x for x in ['a','b','c','d','e'] if x not in ['b','c']]
    

    【讨论】:

    • 实际上,第二个示例中的列表理解比过滤器和 lambda 组合“更 Pythonic”。
    • 谢谢,但我需要将一个这样的循环放入另一个循环中,这样事情就会变得非常混乱。
    【解决方案3】:

    这正是 itertools.ifilter 的设计目的。

    from itertools import ifilter
    
    ifilter(lambda x: x not in ['b', 'c'], ['a', 'b', 'c', 'd', 'e'])
    

    将为您的列表返回一个生成器。如果您确实需要一个列表,您可以使用将生成器转换为列表的标准技术之一来创建它:

    list(ifilter(lambda x: x not in ['b', 'c'], ['a', 'b', 'c', 'd', 'e']))
    

    [x for x in ifilter(lambda x: x not in ['b', 'c'], ['a', 'b', 'c', 'd', 'e'])]
    

    【讨论】:

      【解决方案4】:

      如果您可以创建列表副本,您可以这样做 (list comprehension):

      [s for s in list if s != 'b' and s != 'c']
      

      【讨论】:

        猜你喜欢
        • 2017-08-23
        • 1970-01-01
        • 2014-11-09
        • 2016-08-07
        • 2016-01-02
        • 1970-01-01
        • 2012-08-02
        • 2021-08-09
        相关资源
        最近更新 更多