代码之家  ›  专栏  ›  技术社区  ›  Xolve

迭代时修改列表[重复]

  •  49
  • Xolve  · 技术社区  · 15 年前
    l  = range(100)                         
    for i in l:                         
        print i,                         
        print l.pop(0),                  
        print l.pop(0)
    

    上面的python代码给出的输出与预期的完全不同。我想循环项目,以便在循环时跳过一个项目。

    请解释一下。

    7 回复  |  直到 8 年前
        1
  •  40
  •   Ewan Todd    15 年前

    我以前被(别人的)“聪明”的代码咬过,这些代码试图在遍历列表时修改列表。我下定决心在任何情况下都不干。

    可以使用切片算子 mylist[::3] 跳过到列表中的每三项。

    mylist = [i for i in range(100)]
    for i in mylist[::3]:
      print(i),
    

    关于我的示例的其他要点与 python 3.0 .

    • 我使用列表理解来定义mylist,因为它在python 3.0中工作(见下文)
    • print是python 3.0中的一个函数

    python 3.0 range()现在的行为与xrange()的行为类似,只是它可以处理任意大小的值。后者已不复存在。

        2
  •  49
  •   maxywb    8 年前

    永远不要更改正在循环的容器,因为该容器上的迭代器不会被通知您的更改,而且正如您所注意到的,这很可能会产生非常不同的循环和/或不正确的循环。在正常情况下,在容器副本上循环有帮助,但在您的情况下,很明显 不要 需要这样做,因为在循环的50段之后容器将是空的,如果您再次尝试弹出,您将得到一个异常。

    但最不清楚的是,如果你想达到什么样的行为?也许你可以用一种方式表达你的欲望 while ……?

    i = 0
    while i < len(some_list):
        print i,                         
        print some_list.pop(0),                  
        print some_list.pop(0)
    
        3
  •  11
  •   Paul Sasik    15 年前

    一般的经验法则是,在遍历集合/数组/列表时不要修改它。

    使用辅助列表来存储要操作的项,并在初始循环之后在循环中执行该逻辑。

        4
  •  8
  •   Hank Gay    15 年前

    试试这个。它避免了你正在迭代的东西的变异,这通常是一种代码味道。

    for i in xrange(0, 100, 3):
        print i
    

    xrange .

        5
  •  8
  •   Eugene Eeo    11 年前

    使用while循环检查数组的真实性:

    while array:
        value = array.pop(0)
        # do some calculation here
    

    它应该做到没有任何错误或滑稽行为。

        6
  •  1
  •   York Chang    11 年前

    我想这就是你想要的:

    l  = range(100)  
    index = 0                       
    for i in l:                         
        print i,              
        try:
            print l.pop(index+1),                  
            print l.pop(index+1)
        except:
            pass
        index += 1
    

    当要弹出的项目数是运行时决策时,编写代码非常方便。 但是它的运行效率很差,而且代码很难维护。

        7
  •  0
  •   thethinman    15 年前

    此切片语法将复制列表并执行所需的操作:

    l  = range(100)  
    for i in l[:]:  
        print i,  
        print l.pop(0),  
        print l.pop(0)