Python for循环遍历数组时替换主数组为何未按预期生效?
Python for循环遍历对象不随变量赋值切换的原因说明
问题复现代码
def change_array(array): main_array = array alpha_array = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] for a in main_array: print(main_array, a) if a == 1: main_array = alpha_array if main_array is array else array change_array([1, 1, 0, 0, 0, 1, 0])
运行输出
[1, 1, 0, 0, 0, 1, 0] 1 ['a', 'b', 'c', 'd', 'e', 'f', 'g'] 1 [1, 1, 0, 0, 0, 1, 0] 0 [1, 1, 0, 0, 0, 1, 0] 0 [1, 1, 0, 0, 0, 1, 0] 0 [1, 1, 0, 0, 0, 1, 0] 1 ['a', 'b', 'c', 'd', 'e', 'f', 'g'] 0
原因解释
这个现象的核心逻辑是Python的for循环在启动阶段就固定了遍历使用的迭代器,循环过程中不会因为遍历变量的重新赋值切换遍历源,具体可以拆成三点理解:
- 执行
for a in main_array语句时,解释器只会对in后面的表达式做一次求值:拿到当时main_array指向的原始入参数组,调用数组的__iter__()方法生成专属迭代器。后续整个循环的元素获取,全部依赖这个提前生成的迭代器逐个返回,和main_array变量之后绑定到哪个对象没有关联。 - 循环内的
main_array = xxx赋值操作,只是修改了main_array这个变量名的指向:让它一会绑定原始数组,一会绑定alpha_array,这也是打印main_array时能看到指向的列表来回切换的原因。但这个赋值动作完全触碰不到for循环启动时就生成好的、基于原始数组的迭代器,遍历的元素序列自然不会跟着切换。 - 注意区分「修改变量指向」和「修改原对象内容」的差异:如果循环内不是给
main_array重新赋值,而是直接修改原数组的内容(比如调用append()、pop()增删元素),迭代器是能感知到变化的——因为迭代器本身持有原数组的引用,读取元素时会读取数组的最新内容;但直接把变量名指向另一个全新的列表,和已经生成的迭代器没有任何关系,自然不会改变遍历结果。
内容的提问来源于stack exchange,提问作者sougata das
相关产品推荐
相关产品推荐

