【问题标题】:for-loops being used as while-loops (python)for 循环被用作 while 循环(python)
【发布时间】:2018-07-24 11:49:43
【问题描述】:

我注意到在 Python 中可以使用 for 循环来模拟 while 循环(我对编码知之甚少)。然后,我尝试使用两种不同的公式构建两个相同的 while 循环。在我看来,这里就是这种情况(是吗?)

# for-loop formulation
index = [0]
for a in index:
    if a < 6:
       index.append(a + 1) 

# while-loop formulation
index = [0]
while index[-1] < 6:
    index.append(index[-1] + 1)

让我感到困惑的是,我认为一旦更新/更改了列表索引,for 循环就会从头开始重新启动,因为列表在任何周期都可能发生巨大变化。例如,如果你运行

#3
index = [0]
for a in index:
    print a
    if a < 6:
       index.append(a+1)
       if a > 3:
           index = [1, 3]
    print index

你得到输出

0
[0, 1]
1
[0, 1, 2]
2
[0, 1, 2, 3]
3
[0, 1, 2, 3, 4]
4
[1, 3]
5
[1, 3]

其中 a 不是最后一步中新索引 [1, 3] 的一部分。 因此三个问题:

  1. 一开始的 #1 和 #2 两个程序是否不同(例如,它们的计算量是否不同?)
  2. 程序#3 中发生了什么(为什么'for a in index:' 命令在最后一步显然被忽略了?),以及for 循环一般如何对更新索引的变化作出反应?李>
  3. 是否有关于将 for 循环用作 while 循环的一般指南(我发现它在特定情况下很有帮助,因此我想知道这方面的一些一般提示)。

【问题讨论】:

  • 您对 python 答案还是“一般”答案更感兴趣?
  • 这种行为在 Python 中没有得到很好的记录(有a vague note about it,仅此而已;在bugs.python.org/issue32767 进行讨论)并且依赖它会使阅读您的代码的人感到困惑。使用更明确的 while 循环。
  • 理想情况下,您不应修改被迭代的集合的大小。 while 循环只检查列表的最后一个值,而不是遍历内容
  • 同意@cricket_007:for-loop 和 while-loop 是不同的。如果你要反汇编代码,你会看到 for 循环设置了迭代器,而 while 循环没有。为每个循环创建函数并使用dis 模块将它们反汇编。
  • “让我感到困惑的是,我认为一旦更新/更改了列表索引,for-loop 就会从头开始”它不会。

标签: python python-2.7 for-loop while-loop


【解决方案1】:

前两个基本相同,在不同的情况下它们将运行相同数量的迭代,并且将保持index 处于相同状态。如果将index.append(a+1) 替换为index.append(a),for 循环将永远运行;同样,如果将index.append(index[-1] + 1) 替换为index.append(index[-1]),while 循环将永远运行。像这样修改您正在迭代的列表有点令人担忧,但有时这是一种合理的策略。

顺便说一句,for 循环发生的情况是,当你启动它时,会创建一个迭代器,它给出 index[0],然后是 index[1],然后是 index[2],等等,直到它到达一个不存在的index[N]。这个迭代器不知道也不关心你正在改变列表,所以如果你把列表加长,它会很高兴地继续更长的时间。

在程序 #3 中,范围界定有些混乱。当您进入 for 循环时创建的迭代器并不关心您在 for 循环内重新分配变量 index:它只是不断迭代原始列表。当您在前几次执行index.append(a+1) 时,确实会影响原始列表;但是一旦您执行index = [1, 3],index 就不再引用原始列表,因此您对它所做的任何事情都不会影响剩余的迭代过程。添加的最后一个值是5,因为一旦a 到达4 并且a+1 被附加到索引,index 被破坏并且没有更多的东西被附加到原始列表中。

最后,index 的破坏仍然存在于 for 循环之外:当循环完成时,它将具有值 [1, 3]。

【讨论】:

    猜你喜欢
    • 2012-09-19
    • 1970-01-01
    • 2016-06-07
    • 2017-04-29
    • 1970-01-01
    • 2022-06-28
    • 2019-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多