Python列表更新的正确方式:解决引用重复导致元素覆盖问题
解决Python列表引用导致的元素同步修改问题
你遇到的是Python中可变对象引用的典型坑:因为你始终在操作同一个entry列表对象,每次调用listing.append(entry)添加的都是这个对象的引用,而不是它的独立副本。所以后续修改entry内容时,列表里之前添加的条目也会跟着变化——本质上它们指向的是同一个内存地址。
先看你最初的问题代码:
listing = [] entry = [0.0]*2 entry[0] = 1.0 entry[1] = 2.0 listing.append(entry) # My first entry entry[0] = 2.0 entry[1] = 3.0 listing.append(entry) # Another entry
执行后listing的结果会是[[2.0, 3.0], [2.0, 3.0]],完全不符合你预期的[[1.0, 2.0], [2.0, 3.0]]。
你自己的解法是每次添加后重新创建新的entry列表,虽然能解决问题,但确实有点繁琐:
entry[0] = 1.0 entry[1] = 2.0 listing.append(entry) # My first entry entry = [0.0]*2 entry[0] = 2.0 entry[1] = 3.0 listing.append(entry) # Another entry entry = [0.0]*2
更简洁的实现方法
方法1:使用列表的copy()方法(Python 3.X推荐)
每次添加时,直接传入entry的副本而非引用,这样后续修改原entry就不会影响已经存入listing的内容:
listing = [] entry = [0.0]*2 entry[0] = 1.0 entry[1] = 2.0 listing.append(entry.copy()) # 添加副本,而非原对象引用 entry[0] = 2.0 entry[1] = 3.0 listing.append(entry.copy()) # 再次添加副本
这样listing就能得到你想要的[[1.0, 2.0], [2.0, 3.0]]。
方法2:直接创建新列表(最简洁的场景化写法)
如果不需要复用entry变量,直接在append里创建新列表对象,从根源上避免引用问题:
listing = [] listing.append([1.0, 2.0]) listing.append([2.0, 3.0])
这种写法干净利落,适合数据结构简单的场景。
方法3:用切片生成副本
除了copy(),也可以用切片语法entry[:]生成列表副本,效果完全一致:
listing.append(entry[:])
内容的提问来源于stack exchange,提问作者Jiminion
相关产品推荐
相关产品推荐

