在Python中为for循环变量赋值时的混乱行为

在Python中为for循环变量赋值时的混乱行为,python,python-3.x,python-2.7,loops,for-loop,Python,Python 3.x,Python 2.7,Loops,For Loop,我很好奇为什么下面的Python代码输出数字10..29(步骤1)。使用Python2.7和3进行了测试 for i in range(20): i += 10 print(i) 因此执行i+=10,但尽管它在循环中,但只执行一次。这是一种非常令人困惑的行为 为什么Python的行为如此混乱?实际上,每次执行i+=10,但不影响值 循环开始时的i for i in range(20): # generator range(20) assigns numbers from

我很好奇为什么下面的Python代码输出数字10..29(步骤1)。使用Python2.7和3进行了测试

for i in range(20):
    i += 10
    print(i)
因此执行
i+=10
,但尽管它在循环中,但只执行一次。这是一种非常令人困惑的行为


为什么Python的行为如此混乱?

实际上,每次执行
i+=10
,但不影响值 循环开始时的
i

for i in range(20):
    # generator range(20) assigns numbers from 0 to 19 to i

    i += 10
    # i is now 10 to 29; generator not affected

    print(i)

理解其工作原理的一种方法是将for循环编写为等效的while循环:

it = iter(range(20))
while(True):
    i = next(it)
    i += 10
    print(i)
请注意,
i
在循环的每次迭代中都会从iterable中重新分配一个值。即使
i
的值随着
i+=10
的变化而变化,但在每次重复开始时,它会被更改回循环计数器


(注意:
i=next(it)
将在iterable耗尽后引发异常。为了避免混乱,我没有在这里添加异常处理,以使其在技术上正确。)

为什么要这样做?在
i+=10
之前添加另一个
print()
。我不想在生产代码中这样胡闹,但是尝试这样的事情是有教育意义的。对不起,我应该澄清一下,
range
在Python3中返回一个生成器,但在Python2中返回一个列表。不过,结果是一样的。