在Python的`for`循环中,迭代变量是引用吗?可以用来改变底层数据吗?

43 投票
2 回答
40612 浏览
提问于 2025-04-17 15:30

在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,而不是一个新对象。最终,我们只是把标签重新绑到了同一个气球上。

循环每次迭代时只是给你一个指向列表中下一个项目的引用。它并不会让你改变原来的列表(那只是另一组气球标签);相反,它给你每个包含的项目一个新的标签。

撰写回答