python古怪的乘法_Python下慎用列表的乘法

博主在Python项目中,使用`rows = [[]] * N`初始化列表,处理数据时结果与预期不符。原因是该操作复制的是对象引用而非值拷贝。通过列表表达式`rows = [[] for i in range(N)]`可保证每个元素单独创建,解决引用复制问题。

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

起因

做一个项目时,遇到一个场景,类似于将多行文字录入在二级列表中,即父列表中存放多个子列表,,每个子列表代表一行,所以子列表内的每一项就是一个文字。注意:这只是举例,实际应用中不是存文字,仅仅说明一种类似的场景罢了。

出错

一开始觉得这个挺简单的,因为我是知道有多少行的,所以,我一开始就使用了

rows = [[]] * N

其中N表示行数,这样,我就可以迭代行数据,每一行里的,处理完一个字符,就类似

for i, row in enumerate(data):

for char in row:

processed = process(char) # 处理单个字符

rows[i].append(processed)

结果,实际执行的结果并不是我预想的一样,举例说明一下,假设有两行数据,process函数也是直接返回结果,那么data如果是

[

[1, 2],

[3, 4]

]

的情况,结果应该也是如此才对,结果实际结果如下:

[

[1, 2, 3, 4],

[1, 2, 3, 4]

]

解决

其实看到结果,差不多就知道原因了,问题出在[[]]*N上,根据语义,这里是将[]复制N次,但是这里的操作是复制了对象的引用,而不是值拷贝。

所以,比如[[]]*2得到的[[], []],两个[]元素其实引用的都是同一个,简单的测试即可验证。

a = [[]] * 3

a[0].append(1)

print(a)

这里的结果是[[1], [1], [1]],即对a[0]的操作,和对a[1],a[2]的操作完成一致的。

所以,假设知道是多少行了,其实用以下方法,就可以保证每个元素都是新建的,而不是引用的复制。

rows = [[] for i in range(N)]

这里用了列表表达式,里面每个[]都是单独创建的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值