python列表数乘里的坑

在对列表进行数乘操作时,列表list中元素如为引用类型(列表、对象实例等),则数乘之后,复制出来的每个引用类型的元素都会指向同一个地址。这用会导致后续修改列表元素时,发生一些意料之外的事。接下来我将举例说明。

情况一:列表元素是列表

比如创建一个2*2的二维列表,每个元素都是0,分别用直接创建、数乘、相加、列表推导式的方法创建:

m = [[0,0],[0,0]]
print('m=',m,'第一个元素地址=',id(m[0]),'第二个元素地址=',id(m[1]))
n = [[0,0]]*2
print('n=',n,'第一个元素地址=',id(n[0]),'第二个元素地址=',id(n[1]))
p = [[0,0]]+[[0,0]]
print('p=',p,'第一个元素地址=',id(p[0]),'第二个元素地址=',id(p[1]))
q = [[0,0] for i in range(2)]
print('q=',q,'第一个元素地址=',id(q[0]),'第二个元素地址=',id(q[1]))

用函数id()可以取得四种情况下的列表元素地址:
![代码运行结果截图](https://img-blog.csdnimg.cn/direct/fdc3f3e9e33740
可以看到使用数乘方法创建的二维列表n的两个[0,0]元素地址相同,因而如果修改其中一个元素,另一个元素元素随之改变,而这是我们大部分情况所不希望的:

n[1][0] = 1
print(n)  #输出[[1, 0], [1, 0]]

而使用其它方法创建的二维列表则不会出现上述情况:

q[1][0] = 1
print(q)  #输出[[0, 0], [1, 0]]

情况二:列表元素是对象实例

如果列表元素是一个类的实例时, 也会受到影响:

class A():
    value = 10
a = A()
list1 = [a]
list2 = list1 * 2
print(list1[0].value)					# 输出10
print(list2[0].value,list2[1].value)	# 输出10 10

list2[0].value = 100
print(list1[0].value)					# 输出100
print(list2[0].value,list2[1].value)	# 输出100 100

结论:将数乘替换成列表推导式

比如创建一个10*10的列表,每个元素都是0,可以这么写:

ls = [[0] * 10 for i in range(10)]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值