Python 关于列表中*使用的问题

本文深入探讨了Python中列表嵌套初始化时的浅拷贝现象,解释了为何修改一个子列表会影响所有子列表,并提供了正确的子列表拷贝方法,以避免此类问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在学算法,对算法进行部分修改的时候,无意间遇到了一个列表的问题,那就时列表中*的使用,对此记录总结一下。

当我们想要生成一个嵌套的列表的时候,为了减少代码量,在初始化时,会写成如下的形式(我就是这样的)

li = [[1] * 2] * 3  
print(li)  

输出结果为

[[1, 1], [1, 1], [1, 1]]

而当我们想要对其中的某些子元素进行修改时,我们会天真的写成如下的形式

li[1][0] = 5
print(li)

殊不知,这将会对所有的子列表中的相应的元素进行修改,输出结果为

[[5, 1], [5, 1], [5, 1]]

其实这是因为当我们使用上面*来创建子列表时,相当于浅拷贝(关于浅拷贝和深拷贝的相关内容不再此阐述,读者可自行查阅),当我们修改最内层的元素时,其他的子列表中的元素也会被相应的修改掉,上述代码用for来写的话,可以写为

li_son = [1] * 2
li = []
for i in range(3):
	li.append(li_son)  
print(li)
li[1][0] = 5
print(li)

这边每次for循环,添加的都是同一个对象li_son,因此最后得到的列表相当于[li_son, li_son, li_son], 当我们任意修改其中一个li_son时,对像发生了改变,因此改对象的所有变量都会发生改变。

当我们想只修改其中一个子列表中的某些元素,而不牵涉到其他的子列表的时候,我们可以在for循环创建列表时,可对子列表进行拷贝(需要注意的时,我们这里仅考虑嵌套一层,对于嵌套多层的话,代码将会失效,读者可自行考虑使用深拷贝),由于我们只考虑一层嵌套,所以可以使用简单的list来进行拷贝,代码如下

li_son = [1] * 2
li = []
for i in range(3):
	li.append(list(li_son))   # 创建了一个副本 list(li),但是这个也是浅复制
print(li)
li[1][0] = 5
print(li)

输出结果为

[[1, 1], [1, 1], [1, 1]]
[[1, 1], [5, 1], [1, 1]]

或者使用列表推导

li = [[1] * 2 for i in range(3)]  
print(li)
li[1][0] = 5
print(li)

输出结果为

[[1, 1], [1, 1], [1, 1]]
[[1, 1], [5, 1], [1, 1]]

总结:当使用*来初始化某些列表的时候,其是一种浅拷贝操作,在实际应用中,需考虑后面是否需要对创建的列表进行修改,若需要修改,则需使用深拷贝的操作;单层嵌套的话,最内侧可使用*,因为对于单个列表使用*(如 [1] * 2),修改部分元素,不会修改其他元素。

好好学习,天天向上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值