Python for循环遍历列表时值匹配成功但赋值未生效问题
问题本质
两种遍历写法的核心差异,在于你操作的是「列表内存位置的直接引用」还是「脱离列表的临时循环变量」。
第一种索引遍历能修改成功的原因
对应代码如下:
cities = ['Madrid', 'Barcelona', 'Valencia', 'Murcia'] for city in range(len(cities)): if cities[city] == 'Madrid': cities[city] = 1 elif cities[city] == 'Barcelona': cities[city] = 2 elif cities[city] == 'Valencia': cities[city] = 3 else: cities[city] = 4 print(cities)
这里循环里的city本质是0、1、2、3的索引序号,你每次写cities[city] = 新值的时候,是直接定位到列表在内存中对应下标的存储位置,直接修改该位置保存的内容,所有改动直接作用在原列表上,最终当然能得到修改后的[1, 2, 3, 4]。
第二种直接遍历元素改不动的原因
对应代码如下:
cities = ['Madrid', 'Barcelona', 'Valencia', 'Murcia'] for city in cities: if city == 'Madrid': print('hey') city = 'Kiev' print(cities)
这里的city是循环过程中生成的临时变量,只在当前轮次的循环里生效,保存的是当前遍历到的元素的值。你执行city = 'Kiev'的时候,只是把这个临时变量的指向改成了字符串'Kiev',从头到尾没有触碰原列表对应位置的存储内容。等循环进入下一轮,这个临时变量就会被下一个遍历到的元素覆盖,原列表自然不会有任何变化。
补充一个容易混淆的场景:如果遍历拿到的元素是列表、字典这类可变对象,你调用它自身的修改方法、修改它的内部属性,是会同步改动原列表内容的——因为你没有给临时循环变量重新赋值,只是通过它持有的引用修改了对象本身。但只要你写
临时变量 = 新值这种赋值语句,永远只会修改临时变量本身,和原容器无关。
打个最直白的比方:直接遍历元素拿到的city就像你从花名册上抄下来的一个名字,你把自己草稿纸上的名字涂改成别的,花名册本身不会有任何变化;而用索引定位修改,相当于你直接翻到花名册对应的那一页,在原位置涂改内容,花名册自然就被改了。
对应运行结果也完全符合这个逻辑:
hey ['Madrid', 'Barcelona', 'Valencia', 'Murcia']
内容的提问来源于stack exchange,提问作者zum809
相关产品推荐
相关产品推荐

