关于Python列表初始化与引用的困惑求解
Python列表初始化与引用的疑问解答
核心原因:可变对象与不可变对象的区别
Python中*运算符的行为取决于元素是不可变对象(如数字、字符串、float("inf"))还是可变对象(如列表、字典):
一维列表的行为解析
执行代码:
my_list = [float("inf")] * 3 my_list[2] = 0 print(my_list) # 输出: [inf, inf, 0]
float("inf")是不可变对象,[float("inf")] * 3会创建一个包含3个指向同一inf对象引用的列表。- 当执行
my_list[2] = 0时,不是修改原来的inf对象(不可变对象无法被修改),而是直接替换了列表第3个位置的引用,将其指向新的对象0。因此只有该位置的元素发生变化,其他位置仍保留对原inf的引用。
二维列表的行为解析
执行代码:
my_list = [[float("inf")] * 3] * 3 my_list[2][2] = 0 print(my_list) # 输出: [[inf, inf, 0], [inf, inf, 0], [inf, inf, 0]]
[[float("inf")] * 3]是一个可变的列表对象,*3操作会将这个列表的引用复制3次,存入外层列表。也就是说,外层列表的3个元素都指向同一个内层列表。- 当执行
my_list[2][2] = 0时,是通过引用找到那个唯一的内层列表,直接修改它的第3个元素。由于所有外层列表的元素都指向这个内层列表,所以所有行都会显示出这个修改。
正确的二维列表初始化方式
如果要创建互相独立的子列表,应该使用列表推导式,每次循环创建一个新的内层列表:
my_list = [[float("inf")] * 3 for _ in range(3)] my_list[2][2] = 0 print(my_list) # 输出: [[inf, inf, inf], [inf, inf, inf], [inf, inf, 0]]
这里for _ in range(3)会循环3次,每次都生成一个新的[float("inf")]*3列表,外层列表的3个元素分别指向不同的内层列表,修改其中一个不会影响其他。
内容的提问来源于stack exchange,提问作者Shin
相关产品推荐
相关产品推荐

