【问题标题】:Why Python for loop doesn't work like C for loop?为什么 Python for 循环不像 C for 循环那样工作?
【发布时间】:2012-01-21 16:01:30
【问题描述】:

C:

# include <stdio.h>
main()
{
    int i;
    for (i=0; i<10; i++)
    {
           if (i>5) 
           {
             i=i-1;     
             printf("%d",i);
           } 
    }
}

Python:

for i in range(10):
   if i>5: i=i-1
   print(i)

当我们编译 C 代码时,它会进入一个无限循环,永远打印 5,而在 Python 中不会,为什么不呢?

Python 输出为:

0 1 2 3 4 5 5 6 7 8

【问题讨论】:

  • @spatz 是对的。如果出于某种原因您仍想在 python 中执行此操作,请使用 while 循环
  • 您的问题的答案是“因为它们是不同的语言”。他们不应该以相同的方式工作。如果它们的工作方式相同,它们将是相同的语言。
  • 出现这种情况的原因是,在 C 风格的代码中,您经常需要实际的数字 i,您可以使用它来索引某些数据结构或其他。在 Python 等高级代码中,您通常不希望这样做;迭代将由您要迭代的对象处理。
  • 因为Python和C是不同的语言有不同的semantics

标签: python c for-loop


【解决方案1】:

在 Python 中,循环不会增加 i,而是从可迭代对象(在本例中为列表)为其分配值。因此,在 for 循环内更改 i 不会“混淆”循环,因为在下一次迭代中,i 将被简单地分配下一个值。

在您提供的代码中,当i 为6 时,然后在循环中递减,使其变为5,然后打印。在下一次迭代中,Python 只需将其设置为列表[0,1,2,3,4,5,6,7,8,9] 中的下一个值,即 7,以此类推。当没有更多值可取时,循环终止。

当然,在你提供的 C 循环中得到的效果仍然可以在 Python 中实现。由于每个 for 循环都是一个美化的 while 循环,因此可以这样转换:

for (init; condition; term) ...

相当于:

init
while(condition) {
    ...
    term
}

那么你的 for 无限循环可以用 Python 写成:

i = 0
while i < 10:
    if i > 5:
        i -= 1
    print i
    i += 1

【讨论】:

    【解决方案2】:

    这两个结构都被称为 for 循环,但它们实际上不是一回事。

    Python 的版本实际上是一个 foreach 循环。它为集合中的每个元素运行一次。 range(10) 生成一个类似[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 的列表,因此 for 循环为集合的每个成员运行一次。它不使用i 的值来决定下一个元素是什么,它总是采用列表中的下一个元素。

    c for 循环被翻译成等价于

    int i = 0
    while i < 10:
       ...
       i++;
    

    这就是您可以操纵i 的原因。

    【讨论】:

      【解决方案3】:

      因为你的两个例子是完全不同的东西。

      range(10) 在 python 中生成一个值列表 0 - 9,然后 for i in 将每个 返回为 i。这通常被称为“for-each”循环。当您在 python 示例中说 i=i-1 时,您正在操作一个值,而不是迭代器。

      【讨论】:

        【解决方案4】:

        http://docs.python.org/tutorial/controlflow.html

        Python 中的for 语句与您在C 或Pascal 中可能使用的语句有些不同。 Python 的 for 语句迭代任何序列的项目(列表或一个字符串),按照它们在序列中出现的顺序。例如(没有双关语):

        a = ['cat', 'window', 'defenestrate']
        for x in a:
            print x, len(x)
        

        在循环中修改被迭代的序列是不安全的(这只会发生在可变序列类型上,例如列表)。如果您需要修改您正在迭代的列表(例如,复制所选项目),您必须迭代一个副本。

        range生成的序列当然是不可变的。

        【讨论】:

        • 范围序列在python 2.x中是可变的
        • 我猜如果你将结果分配给一个列表,但在示例问题中它似乎不会发生变化/变异吗?
        • 你的回答很好,只是我反对说 range 生成的序列是不可变的。你可以改变对象,只是你无法访问它,除非你先将它存储为本地。
        猜你喜欢
        • 1970-01-01
        • 2022-11-12
        • 1970-01-01
        • 2022-06-12
        • 2013-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多