1. 程式人生 > >python3 踩坑之:*操作符生成二維列表

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

可以看到,這樣就不是同一個物件了,問題解決~