python3 踩坑之:*操作符生成二維列表
阿新 • • 發佈:2018-12-16
引言
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
可以看到,這樣就不是同一個物件了,問題解決~