python3 踩坑之:*操作符生成二维列表

引言

    python中“*”操作符是序列(列表,字符串和元组)的通用操作符,可以实现序列的复制,比如:

>>> [1,2,3]*3    #复制列表
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> ('hello',)*3  #复制元组
('hello', 'hello', 'hello')
>>> 'aa'*3    #复制字符串
'aaaaaa'

问题

  但是对嵌套的列表使用*操作时,要特别注意,列表是可变对象,复制后的是同一个对象。比如,生成一个3*3的二维列表:

>>> a = [[0]*3]*3#生成初始值为0的3*3的二维列表
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[0][1]=9  #将a[0][1]的值改为9
>>> a
[[0, 9, 0], [0, 9, 0], [0, 9, 0]]

可以看到改变的是a[0][1]的值,但是a[1][1]和a[2][1]的值也都修改了,也就是说二维列表a中的三个一维列表其实是同一个!!上代码证明之:

>>> id(a[0])
2808969334344
>>> id(a[1])
2808969334344
>>> id(a[2])
2808969334344

果然,id()取出来的地址是完全一样的

解决方法

如果又想用*操作符去生成二维列表改怎么办呢?可以用推导列表的方式解决,如下:

>>> a=[[0]*3 for i in range(3)]
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[0][1]=9
>>> a
[[0, 9, 0], [0, 0, 0], [0, 0, 0]]
>>> id(a[0])
2808969334472
>>> id(a[1])
2808969334216
>>> id(a[2])
2808969334024

可以看到,这样就不是同一个对象了,问题解决~

猜你喜欢

转载自blog.csdn.net/kongsuhongbaby/article/details/83145467
今日推荐