You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修改嵌套列表时,`for item in list`与`for i in range(len(list))`的差异

关于Python中for循环修改列表元素的困惑

问题背景

原地修改一维列表时,索引循环可行,但for-each循环不可行:
可行代码:

l = [1, 2, 3]
for i in range(len(l)):
    l[i] += 1

不可行代码:

l = [1, 2, 3]
for num in l:
    num += 1

一般认为for-each循环中num是列表元素的副本,但嵌套列表的情况却打破了这个认知:

嵌套列表时,以下两段代码均可行:
可行代码1:

l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for i in range(len(l)):
    for j in range(len(l[i])):
        l[i][j] += 1

可行代码2:

l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for sublist in l:
    for i in range(len(sublist)):
        sublist[i] += 1

而以下代码不可行:

l = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for sublist in l:
    for num in sublist:
        num += 1

困惑点:如果for-each循环会创建列表元素的副本,那第二段可行代码中的sublist应该是原列表中子列表的副本,修改sublist的元素不应改变原列表l,但实际却生效了,这是为什么?


核心解释:Python的变量是引用,区分可变与不可变类型

首先纠正一个误区:for-each循环里的变量不是元素的副本,而是指向元素的引用。能不能修改原列表,关键看元素本身是可变类型还是不可变类型:

  1. 一维列表(元素为不可变类型)
    列表中的整数是不可变类型。当执行for num in l时,num是指向列表中某个整数的引用,但整数无法被修改——num += 1本质是创建了一个新的整数对象,让num转而指向这个新对象,原列表里的元素还是原来的整数,所以原列表不会有变化。
    而用索引l[i] += 1时,是直接对列表索引i位置的元素进行重新赋值,把新整数放到该位置,所以原列表会被修改。

  2. 嵌套列表(外层元素为可变类型)
    外层列表的元素是子列表(可变类型)。for sublist in l中的sublist是指向原列表中子列表对象的引用,不是副本。当你通过sublist[i] += 1修改这个子列表的元素时,本质是在操作原列表中存储的那个子列表对象,原列表自然会跟着变化。
    最后那段两层for-each的代码里,内层的num指向的是子列表里的整数(不可变类型),num +=1同样是创建新整数,不会修改原有的子列表元素,所以原列表没变化。

总结

  • 元素为不可变类型(int、str、tuple等):for-each循环里修改变量不会影响原列表,因为变量指向了新对象。
  • 元素为可变类型(list、dict等):for-each循环里的变量指向原对象,修改对象内部的元素会影响原列表,因为操作的是同一个对象。

内容的提问来源于stack exchange,提问作者Raymond Li

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 08:52:37