1、標識、相等性和別名 別名的例子 >>> charles = {'name': 'Charles L. Dodgson', 'born': 1832} >>> lewis = charles >>> lewis is charles True >>> id(charles) 13999618526 ...
1、標識、相等性和別名
- 別名的例子
>>> charles = {'name': 'Charles L. Dodgson', 'born': 1832} >>> lewis = charles >>> lewis is charles True >>> id(charles) 139996185268800 >>> id(lewis) 139996185268800
2.相等性的例子
>>> charles = {'name': 'Charles L. Dodgson', 'born': 1832} >>> alex = {'name': 'Charles L. Dodgson', 'born': 1832} >>> alex == charles True >>> alex is charles False >>> id(alex) 139996185193136 >>> id(charles) 139996185268800備註:== 運算符比較兩個對象的值(對象中保存的數據),而 is 比較對象的標識。 is 運算符比 == 速度快,因為它不能重載,所以 Python 不用尋找並調用特殊方法,而是直接比較兩個整數 ID。 而 a == b 是語法糖,等同於 a.__eq__(b) 。
2、預設做淺複製
複製列表(或多數內置的可變集合)最簡單的方式是使用內置的類型構造方法。
>>> l1 = [12,123,22,213,222,1221] >>> l2 = list(l1) >>> l2 == l1 True >>> l2 is l1 False創建 l1的副本,l2和l1相等,但是l2和l1是不同的對象;也可以這個樣複製, l2 = l1[:] 然而,構造方法或 [:] 做的是淺複製(即複製了最外層容器,副本中的元素是源容器中元素的引用)。 如果所有元素都是不可變的,那麼這樣沒有問題,還能節省記憶體。但是,如果有可變的元素,可能就會導致意想不到的問題。
>>> l1 = [3, [66,55,44], (7,8,9)] >>> l2 = l1[:] >>> l1.append(100) >>> l1 [3, [66, 55, 44], (7, 8, 9), 100] >>> l1[1].remove(55) >>> print('l1', l1) l1 [3, [66, 44], (7, 8, 9), 100] >>> print('l2', l2) l2 [3, [66, 44], (7, 8, 9)] >>> l2[1] += [33,22] >>> l2[2] += (10,11) >>> print('l1', l1) l1 [3, [66, 44, 33, 22], (7, 8, 9), 100] >>> print('l2', l2) l2 [3, [66, 44, 33, 22], (7, 8, 9, 10, 11)]解釋一下上面發生的現象,l1裡面有三個元素, 分別是3,[66,55,44],(7,8,9);l1引用這三個,l2也引用這三個 當l1進行append 時,不會對l2造成影響;但是l1刪除55的時候,l1的引用變成了[66,44] 此時l2的引用也變成了這個; 當l2對[66,44] + [33,22]時,l2和l1的引用都會變;但是當l2改變了元組(7,8,9)時,(元組是不可變對象)此時l2引用的元組變了(7,8,9,10,11),但是l1的 引用還是(7,8,9)
3、深複製
淺複製沒什麼問題,但有時我們需要的是深複製(即副本不共用內部對象的引用)。 copy模塊提供的 deepcopy 和 copy 函數能為任意對象做深複製和淺複製。import copy class Bus(object): def __init__(self, passengers=None): if passengers is None: self.passengers = [] if passengers is not None: self.passengers = list(passengers) def drop(self, name): self.passengers.remove(name) def pick(self, name): self.passengers.append(name) bus1 = Bus(['Alice', 'Bill', 'Claire', 'David']) bus2 = copy.copy(bus1) bus3 = copy.deepcopy(bus1) bus1.drop('Bill') bus1.pick('tom') print(bus1.passengers) print(bus2.passengers) print(bus3.passengers) # ------------------------- # bus1 ['Alice', 'Claire', 'David', 'tom'] # bus2 ['Alice', 'Claire', 'David', 'tom'] # bus3 ['Alice', 'Bill', 'Claire', 'David']
淺複製時,bus1和bus2,公用了一個列表對象,這個是可變對象