【问题标题】:Why does the "j" recognize the change in range, while the "i" does not?为什么“j”能识别范围的变化,而“i”却不能?
【发布时间】:2019-04-30 17:45:34
【问题描述】:

我正在编写一些代码,我遇到的情况类似于下面提供的代码。似乎在第二个 for 循环中,正在识别 num 的值的变化,而在第一个 for 循环的值中却没有。为什么不呢,我将如何以它可以识别的方式编写它?

num=3
for i in range(num):
    for j in range(num):
        print(i, j)
        if num<5:
            num=num+1

代码以我期望的 (0, 0)、(0, 1) 等开始,但在 (2, 4) 结束,因为 j 已达到其范围的末尾。我不明白为什么第一个 for 循环不知道 num 已更新。

【问题讨论】:

    标签: python for-loop range


    【解决方案1】:

    您似乎希望您的 for 循环表现得像一个 while 循环。

    让我们写一个稍微简单的例子来看看发生了什么。

    num = 5
    for j in range(num):
        print(j)
        if j == 3:
            num = num + 1
    

    输出

    0
    1
    2
    3
    4
      <--- No 5
    

    您似乎期望上面的行为等同于以下代码的 sn-p。

    num = 5
    j = 0
    while j < num:
        print(j)
        if j == 3:
            num += 1
        j += 1
    

    输出

    0
    1
    2
    3
    4
    5  <-- updating num added a value in the output
    

    for 循环与 while 循环

    for 循环和 while 循环之间的根本区别在于,只要条件为真,while 循环就会运行,并且它重新评估每次迭代的条件。同时,for 循环遍历可迭代对象(在这种情况下为 range)中的项目,可迭代对象不会在每次操作时重新计算

    range对象

    让我们看看另一个例子,它解释了为什么当num 递增时,可迭代的range(num) 没有更新。

    num = 5
    r = range(num)
    print(r) # range(0, 5)
    
    num += 1
    print(r) # still range(0, 5)
    

    当调用range(num) 时,会创建一个可迭代对象。它接收值5 作为上限,根本不关心名称num。如您所见,当num 更新时,对象r 不受影响。为什么会呢?它被赋予了值5,这就是它所关心的。

    回到你的代码

    如果for循环的iterable没有被重新计算,那为什么内部循环并不总是一样呢?

    嗯,正是因为内循环在每次迭代中运行。在外循环的每次迭代中,都会为内循环创建一个新对象range(num),并且由于此时num 已更新,因此新创建的range 与初始对象不同。

    【讨论】:

      【解决方案2】:
      def main():
          num=3
          for i in range(num):
              # Exiting nested for-loop causes range(num) to be re-evaluated
              for j in range(num):
                  print(i, j)
                  if num < 5:
                      num=num+1
      
          # Now that we have exited the first for-loop,
          # range(num) is re-evaluated and 0,1,2,3,4 is printed
          for i in range(num):
              print(i)
      
      if __name__ == '__main__':
          main()
      

      【讨论】:

        【解决方案3】:

        num 值在 for 循环被调用时被锁定。 num 的值仅在调用时更新,而不是在执行时更新。

        【讨论】:

          【解决方案4】:

          ‘range(num)‘只被评估一次,而不是在每次迭代中。所以相当于

          for i in range(3):
              for j in range(num):
                  # do something with i and j
          

          【讨论】:

          • 不完全是,在示例代码中,for j in range(num): 行将在 i 的下一个循环中重新评估
          猜你喜欢
          • 2022-01-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-28
          • 2011-07-25
          相关资源
          最近更新 更多