在Python的`for`循环中,迭代变量是引用吗?可以用来改变底层数据吗?
在Python中,当你用for
循环来遍历一个列表里的项目时,如果你改变了item
(下面的代码),这会影响到items
里的对应项目吗?
for item in items:
item += 1
在循环中,items
里的每个项目会被增加,还是在循环之前保持不变呢?
2 个回答
14
其实,这个问题的答案主要看具体的情况。
举个例子:
class test():
pass
a = test()
a.value = 1
b = test()
b.value = 2
l = [a,b]
for item in l:
item.value += 1
for item in l:
print item.value
>>>
2
3
再来看另一个例子:
l2 = [1,2,3]
for item in l2:
item += 1
for item in l2:
print item
>>>
1
2
3
所以,正如Martijn所说,你需要理解指针的概念。
38
不,Python中的变量不是指针。
它们实际上是指向堆上的对象,给变量赋值并不会改变被引用的对象,而是改变了变量本身。可以把变量和对象想象成绑在气球上的标签;赋值就像是把标签换到另一个气球上。
你可以看看我之前的一个回答,更深入地了解气球和标签的这个想法。
不过,有些对象类型实现了特定的就地添加行为。如果对象是可变的(气球本身可以改变),那么就地添加可能被理解为一种变更,而不是简单的赋值。
所以,对于整数来说,item += 1
实际上和item = item + 1
是一样的,因为整数是不可变的。你必须创建一个新的整数对象,并把item
这个标签绑到那个新对象上。
而列表则是可变的,lst += [other, items]
实际上是执行lst.__iadd__([other, items])
,这会改变lst
这个气球本身。虽然仍然会发生赋值,但这只是对同一个对象的重新赋值,因为.__iadd__()
方法返回的仍然是self
,而不是一个新对象。最终,我们只是把标签重新绑到了同一个气球上。
循环每次迭代时只是给你一个指向列表中下一个项目的引用。它并不会让你改变原来的列表(那只是另一组气球标签);相反,它给你每个包含的项目一个新的标签。