Python 为什么这两个代码给出相同的结果?
代码1: 代码2: 两者的结果: 为什么第二个代码中的递增对结果没有影响?从迭代中获得的i值是枚举函数的输出,而不是它的输入 修改它不会影响枚举过程,并且for…in循环将使用枚举生成的内容不断覆盖变量,而不管您在循环体中将其设置为什么 与Java和C不同的是,python中的循环会在上下循环。它们不依赖于计数器。从迭代中获得的i值是枚举函数的输出,而不是它的输入 修改它不会影响枚举过程,并且for…in循环将使用枚举生成的内容不断覆盖变量,而不管您在循环体中将其设置为什么Python 为什么这两个代码给出相同的结果?,python,python-3.x,Python,Python 3.x,代码1: 代码2: 两者的结果: 为什么第二个代码中的递增对结果没有影响?从迭代中获得的i值是枚举函数的输出,而不是它的输入 修改它不会影响枚举过程,并且for…in循环将使用枚举生成的内容不断覆盖变量,而不管您在循环体中将其设置为什么 与Java和C不同的是,python中的循环会在上下循环。它们不依赖于计数器。从迭代中获得的i值是枚举函数的输出,而不是它的输入 修改它不会影响枚举过程,并且for…in循环将使用枚举生成的内容不断覆盖变量,而不管您在循环体中将其设置为什么 与Java和C不同的
与Java和C不同的是,python中的循环会在上下循环。它们不依赖于计数器。通过查看CPython在第二个示例中生成的字节码,可以找到一些见解:
>>> from dis import dis
>>> def with_increment():
for i, x in enumerate(data, 1):
print(i, x)
i += 1
>>> dis(with_increment)
2 0 SETUP_LOOP 40 (to 42)
2 LOAD_GLOBAL 0 (enumerate)
4 LOAD_GLOBAL 1 (data)
6 LOAD_CONST 1 (1)
8 CALL_FUNCTION 2
10 GET_ITER
>> 12 FOR_ITER 26 (to 40)
14 UNPACK_SEQUENCE 2
16 STORE_FAST 0 (i)
18 STORE_FAST 1 (x)
3 20 LOAD_GLOBAL 2 (print)
22 LOAD_FAST 0 (i)
24 LOAD_FAST 1 (x)
26 CALL_FUNCTION 2
28 POP_TOP
4 30 LOAD_FAST 0 (i)
32 LOAD_CONST 1 (1)
34 INPLACE_ADD
36 STORE_FAST 0 (i)
38 JUMP_ABSOLUTE 12
>> 40 POP_BLOCK
>> 42 LOAD_CONST 0 (None)
44 RETURN_VALUE
我们感兴趣的部分是字节12-38,它对应于循环体。每次迭代开始时,按顺序执行以下操作:
UNPACK_SEQUENCE 2-枚举生成的元组的组件被推送到堆栈上
STORE_FAST 0-堆栈顶部的值存储在第一个局部变量i中
STORE_FAST 1-堆栈顶部的值存储在第二个局部变量x中
这里需要注意的关键是,我们从不看i的当前值——每次迭代都会盲目地用迭代器生成的任何内容覆盖它。在上一次迭代中,i中使用的任何对象都被完全遗忘。通过查看CPython在第二个示例中生成的字节码,可以找到一些见解:
>>> from dis import dis
>>> def with_increment():
for i, x in enumerate(data, 1):
print(i, x)
i += 1
>>> dis(with_increment)
2 0 SETUP_LOOP 40 (to 42)
2 LOAD_GLOBAL 0 (enumerate)
4 LOAD_GLOBAL 1 (data)
6 LOAD_CONST 1 (1)
8 CALL_FUNCTION 2
10 GET_ITER
>> 12 FOR_ITER 26 (to 40)
14 UNPACK_SEQUENCE 2
16 STORE_FAST 0 (i)
18 STORE_FAST 1 (x)
3 20 LOAD_GLOBAL 2 (print)
22 LOAD_FAST 0 (i)
24 LOAD_FAST 1 (x)
26 CALL_FUNCTION 2
28 POP_TOP
4 30 LOAD_FAST 0 (i)
32 LOAD_CONST 1 (1)
34 INPLACE_ADD
36 STORE_FAST 0 (i)
38 JUMP_ABSOLUTE 12
>> 40 POP_BLOCK
>> 42 LOAD_CONST 0 (None)
44 RETURN_VALUE
我们感兴趣的部分是字节12-38,它对应于循环体。每次迭代开始时,按顺序执行以下操作:
UNPACK_SEQUENCE 2-枚举生成的元组的组件被推送到堆栈上
STORE_FAST 0-堆栈顶部的值存储在第一个局部变量i中
STORE_FAST 1-堆栈顶部的值存储在第二个局部变量x中
这里需要注意的关键是,我们从不看i的当前值——每次迭代都会盲目地用迭代器生成的任何内容覆盖它。在上一次迭代中,i中的任何对象都被完全遗忘。i的值在每次迭代中都会自动更新。不管您如何更改它,这些更改都会被覆盖。Python for循环用于每个循环,而不是init test increment循环。拧动循环变量不会影响for each循环中的下一个元素。@DYZ我理解,但是使用什么机制来记住I的前一个状态呢?这与python中作用域变量的概念有关吗?请提供预期的输出。关键是在迭代之间我不会被记住。枚举有它自己的内部计数器,它与i分开。i的值在每次迭代时自动更新。不管您如何更改它,这些更改都会被覆盖。Python for循环用于每个循环,而不是init test increment循环。拧动循环变量不会影响for each循环中的下一个元素。@DYZ我理解,但是使用什么机制来记住I的前一个状态呢?这与python中作用域变量的概念有关吗?请提供预期的输出。关键是在迭代之间我不会被记住。enumerate有自己的内部计数器,它与i分开。
1 A
2 B
3 C
4 D
>>> from dis import dis
>>> def with_increment():
for i, x in enumerate(data, 1):
print(i, x)
i += 1
>>> dis(with_increment)
2 0 SETUP_LOOP 40 (to 42)
2 LOAD_GLOBAL 0 (enumerate)
4 LOAD_GLOBAL 1 (data)
6 LOAD_CONST 1 (1)
8 CALL_FUNCTION 2
10 GET_ITER
>> 12 FOR_ITER 26 (to 40)
14 UNPACK_SEQUENCE 2
16 STORE_FAST 0 (i)
18 STORE_FAST 1 (x)
3 20 LOAD_GLOBAL 2 (print)
22 LOAD_FAST 0 (i)
24 LOAD_FAST 1 (x)
26 CALL_FUNCTION 2
28 POP_TOP
4 30 LOAD_FAST 0 (i)
32 LOAD_CONST 1 (1)
34 INPLACE_ADD
36 STORE_FAST 0 (i)
38 JUMP_ABSOLUTE 12
>> 40 POP_BLOCK
>> 42 LOAD_CONST 0 (None)
44 RETURN_VALUE