案例一:
def test():
a = [1, 2]
for i in a:
print(i, id(a))
if i == 5:
break
a = [a[0]+2, a[1]+2]
输出:
1 4313456192
2 4313269056
解释:
在for循环语句中的变量a使用的内存地址为4313456192,这个地址以及存储的值不会因为a的重新赋值而改变,换句话说就是for循环的对象是一块固定的内存地址中的值。所以循环遍历的目标始终是[1,2]。
还要注意的是id(a),每次打印的是a变量所指的内存地址,对a重新赋值是会改变a所指向的内存地址,也就是通常说的变量a只是内存地址的引用。
案例二:
def test():
a = [1, 2]
for i in a:
print(i, id(a))
if i == 5:
break
a[1] = 5
# a.append(5)
# a.extend([3, 4])
输出:
1 4344831488
5 4344831488
解释:
明白了案例一,这个案例就不难解释了,因为for循环对象的内存地址不变,a[1] = 5表示修改这块内存地址的值。所以会输出1,5。append、extend、insert、pop操作也是同样的道理,这些操作并不会改变for循环对象的内存地址。
但要注意insert、pop的使用,如果语句体从序列中删除了当前(或之前)的一项,下一项就会被跳过(因为其标号将变成已被处理的当前项的标号)。 类似地,如果语句体在序列当前项的前面插入一个新项,当前项会在循环的下一轮中再次被处理。移步案例三。
案例三:
def test():
a = [1, 2, 3, 5]
for i in a:
print(i, id(a))
a.insert(0, 5)
# a.pop(0)
输出:
1
1
1
1...
无限循环1
解释:
循环体会有一个内部计数器被用来跟踪下一个要使用的项,每次迭代都会使计数器递增。 当计数器值达到序列长度时循环就会终止。
pop(0)操作时:
所以只会输出1, 3。