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

迭代列表时如何修改元素?两种场景差异及原因解析

为什么Python迭代列表时修改元素的行为不一致?

先明确两个案例的现象:

  • 案例一中,迭代整数列表执行l += 1后,原列表内容无变化,输出仍为[0, 1, 2, 3, 4]
  • 案例二中,迭代类实例列表调用set_n方法后,所有实例的属性都被修改,输出为[4, 4, 4, 4, 4]

核心差异与背后原因

1. 数据类型的可变性差异

Python中的数据类型分为不可变类型(如整数、字符串、元组)和可变类型(如列表、字典、自定义类实例),这是两种行为差异的根本原因:

案例一:不可变类型的特性

整数属于不可变类型,执行l += 1时:

  • 迭代过程中,l是列表中整数元素的引用拷贝
  • 因为整数不可变,l += 1并不是修改原整数对象,而是创建了一个值为原数+1的新整数对象
  • 此时l指向新对象,但原列表中的元素仍指向原来的整数对象,所以原列表内容不会改变

案例二:可变类型的特性

自定义类的实例属于可变类型,调用l.set_n(4)时:

  • 迭代过程中,l是列表中实例对象的引用拷贝,但这个引用和列表中存储的引用指向同一个实例对象
  • set_n方法直接修改该实例对象内部的self.n属性,没有创建新实例
  • 原列表中存储的引用仍指向被修改的实例,因此遍历列表时能看到属性变化

2. 额外说明:[Foo(3)] * 5的特性

案例二中list_2 = [Foo(3)] * 5会创建包含5个相同实例引用的列表——这5个元素其实指向同一个Foo实例。所以调用任意一个元素的set_n方法,都会修改这个唯一的实例,最终所有元素的n属性都会变成4,这是可变类型引用复用的特性,和迭代修改的逻辑相辅相成。

示例代码

# 案例一:修改整数列表
list_1 = [0, 1, 2, 3, 4]
for l in list_1:
    l += 1
print(list_1)  # 输出: [0, 1, 2, 3, 4]

# 案例二:修改类实例列表
class Foo:
    def __init__(self, n):
        self.n = n
        
    def set_n(self, n):
        self.n = n
        
list_2 = [Foo(3)] * 5
for l in list_2:
    l.set_n(4)
print([l.n for l in list_2])  # 输出: [4, 4, 4, 4, 4]

内容的提问来源于stack exchange,提问作者G. Gare

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 10:48:21