1. list對象的*操作符
>>> a = [[1]]*10
>>> a
[[1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]
>>> a[1][0] = 2
>>> a
[[2], [2], [2], [2], [2], [2], [2], [2], [2], [2]]
>>>
也就是說,這10個對象實際上是指向的同一個list對象。
這是bug,還是feature?或者是優(yōu)化?
總之是蠻讓人火大的就是了。
用 a = [[0] for x in range(10)] 這種寫法就沒有這個問題了。
2. 深拷貝
>>> a = [[0] for x in range(10)]
>>> a
[[0], [0], [0], [0], [0], [0], [0], [0], [0], [0]]
>>> b = list(a)
>>> b
[[0], [0], [0], [0], [0], [0], [0], [0], [0], [0]]
>>> a[1][0] = 2
>>> b
[[0], [2], [0], [0], [0], [0], [0], [0], [0], [0]]
>>>
b = list(a)
意味著a和b中都存放這10個指針。指向[0], [0], [0] .... 這10個對象。
a[1][0] = 2 后 a 自己的值沒有改變,改變的是第二個 [0] 對象。
由于 b 也是指向它的,所以打印b的時候會發(fā)現(xiàn)這一點。
這個問題是自己經常犯的問題,大多都是debug半天才知道怎么回事。
使用
import copy
b = copy.deepcopy(a)
可以解決這個問題。
3. 如何避免這些問題
要時刻記得,python中的對象就只有兩種,mutable和immutable。也就是可改變和不可改變。
immutable的包括:str tuple int ...
mutable可改變的包括:list dict ...
immutable的就是原子的。mutable里面存放的都是指向mutable或者immutable的指針。
調試的時候,可以使用id(obj)獲得每個對象的id。這個貌似就是python管理的運行時的對象的地址。
如果發(fā)現(xiàn)兩個obj的id相同,那他們就是同一個貨。。