【问题标题】:Loop counter behaving unexpectedly循环计数器行为异常
【发布时间】:2022-01-21 03:27:56
【问题描述】:

我无法理解为什么计数器变量即使在 嵌套循环,对父循环运行的次数没有任何影响!

当嵌套循环内的增量应该阻止它执行第二次和第三次时,下面的代码给出了输出0 1 2

for i in range(3):
  print(i)
  for j in range(2):
    i = i + 2

嵌套内的i是否指向不同的i

【问题讨论】:

  • 你迭代 range 对象,你期望什么?
  • 它在 python 中不是这样工作的。
  • @SashSinha 为什么每次循环运行时都要重新分配“i”!我对循环的理解是“i”将在循环开始时初始化,然后继续使用该值。它与范围调用有关,例如创建上下文“i”!
  • 不,这不是 Python 中 for 循环的工作方式。它从可迭代对象中消费一个项目并将该项目分配给迭代变量,然后运行块中的代码。重复此操作,直到可迭代对象用完为止。
  • i 在每次迭代开始时被分配一个值来自 range 对象的迭代器;循环第一次开始时它不会被初始化一次。

标签: python python-3.x loops for-loop


【解决方案1】:

如果你在循环增加它之后显示i,你会看到变化

for i in range(3):
    print(i)
    for _ in range(2):  # j is not used
        i += 2
    print(i)  # I'm new!

每次运行第一行时,它都会使用 range() 序列中的下一个值重新标记 i,丢弃之前的值

【讨论】:

    【解决方案2】:

    您不会将增量的结果存储在任何地方。它是这样的:i 被分配一个来自 range() 的值,你打印它,然后 j 得到分配的值,i += 1,然后你再次开始循环,i 被分配下一个值来自range()。 这应该可以工作

    for i in range(3):
    
      for j in range(2):
         
        i = i + 2
        print(i)
    

    【讨论】:

      【解决方案3】:

      要达到您正在寻找的效果,您必须增加迭代器。你可能认为它是递增指针,而不是指针处的值:

      iterator = iter(range(123))
      
      for i in iterator:
          print(i)
          next(iterator, None) #None here is a default, 
                               #and stops you getting an error if there is no 'next'.
      
            
      

      想象一下,python 中的 for 循环正在执行以下操作,这很明显为什么分配给循环主体内的 i 的值会丢失。当您真的想增加 n 时,您正在增加 i

      iterator = list(range(10))
      n = 0
      while n < len(iterator):
          n+=1
          i = iterator[n]
          print(i)
          i = i+1
      

      【讨论】:

        【解决方案4】:

        for 循环是一种奇特的赋值语句;循环索引在每次迭代开始时分配给。

        代码

        for i in range(3):
          print(i)
          for j in range(2):
            i = i + 2
        

        实际上等价于

        itr1 = iter(range(3))
        while True:
            try:
                i = next(itr1)
            except StopIteration:
                break
        
            itr2 = iter(range(2))
            while True:
                try:
                    j = next(itr2)
                except StopIteration:
                    break
        
                i = i + 2
        

        i = next(itr1) 的赋值忽略了之前迭代中对i 所做的任何其他操作:该值仅取决于itr1 的状态,而不是i 的当前值。

        【讨论】:

          猜你喜欢
          • 2018-03-26
          • 1970-01-01
          • 2014-07-01
          • 2013-07-30
          • 2021-11-27
          • 2010-10-12
          • 2011-01-17
          • 2023-03-22
          • 1970-01-01
          相关资源
          最近更新 更多