python拷貝物件 Python物件的比較 拷貝

2021-10-21 05:45:19 字數 1641 閱讀 5572

比較比較操作符 『==』 表示比較物件間的值是否相等,而 『is』 表示比較物件的標識是否相等,即他們是否指向同乙個記憶體位址

比較操作符 『is』 效率優於 『==』,因為 『is』 不能被過載,執行 『is』 操作只是簡單的獲取物件的 id,並進行比較,而 『==』 操作符則會遞迴的遍歷物件的所有值,並逐一比較。

淺拷貝淺拷貝中的元素,是原物件中子物件的引用,因此,如果原物件中的元素是可變的,改變其他也會影響拷貝後的物件,存在一定的***。

l1 = [[1, 2], (30, 40)]

l2 = list(l1)

l1[[1, 2, 3], (30, 40), 100]

l2[[1, 2, 3], (30, 40)]

l1[1] += (50, 60)

l1[[1, 2, 3], (30, 40, 50, 60), 100]

l2[[1, 2, 3], (30, 40)]

在這個例子中,我們先初始化了乙個列表 l1,裡面的元素是乙個列表和乙個元組;然後對 l1 執行淺拷貝,賦予 l2,因為淺拷貝裡的元素是對原物件元素的引用,因此 l2 中元素和 l1 指向同乙個列表和元組物件。

最後是l1[1] +=(50,60),因為元組是不可變的,這裡表示對 l1 中的第二個元組拼接,然後重新創造了乙個新元組作為 l1 中的第二個元素,而 l2 沒有引用新元組,因此 l2 並不受影響,操作後 l2 不變,l1 發生改變。

深拷貝深拷貝則會遞迴地拷貝原物件中的每個子物件,因此拷貝後的物件和原物件互不相關,另外,深拷貝會維護乙個字典,記錄已經拷貝的物件及其 id,來提高效率並防止無止境的遞迴發生。

import copy

l1 = [[1, 2], (30, 40)]

l2 = copy.deepcopy(l1)

l1[[1, 2, 3], (30, 40), 100]

l2[[1, 2], (30, 40)]

deepcopy()原始碼

def deepcopy(x, memo=none, _nil=):

"""deep copy operation on arbitrary python objects.

see the module's __doc__ string for more info.

if memo is none:

memo = {}

d = id(x) # 查詢被拷貝物件x的id

y = memo.get(d, _nil) # 查詢字典裡是否已經儲存了該物件

if y is not _nil:

return y # 如果字典裡已經儲存了將要拷貝的物件,則直接返回

思考import copy

x = [1]

y = copy.deepcopy(x)

# 以下命令的輸出是?

x == y

traceback (most recent call last):

file "", line 1, in

recursionerror: maximum recursion depth exceeded in comparison

因為 x 是乙個無限巢狀的列表,y 深度拷貝 x 也是乙個無限巢狀的列表,理論上 x == y 應該返回 true,但是 x == y 內部執行是會遞迴遍歷列表內部的,由於無限巢狀,因此報錯。

Python 拷貝物件

最近做python工程,由於一直用c 沒有系統學習過python,犯了乙個嚴重的錯誤,那就是python中的物件之間賦值 時是按引用傳遞!也就是更改了賦值的新物件,兩個值都會變化。如果需要拷貝物件,需要使用標準庫中的copy模組。a 1 2,3 4,a b b a b 2 10 print b b ...

拷貝python物件,淺拷貝和深拷貝

物件賦值實際上是簡單的物件引用。也就是說建立乙個物件然後賦值給另乙個變數的時候,python並沒有拷貝這個物件,而是拷貝了這個物件的引用。淺拷貝 淺拷貝的是物件本身,但是內容是原來物件的引用。拷貝物件本身是新的但是內容不是新的 拷貝物件的方式 來看 import copy a a b c 1,2,3...

python物件引用 深淺拷貝

python是引用計數的方式來管理的。那麼python 真的是 傳物件引用?實際上,python是採用傳值和傳引用結合的一種方式。如果函式收到的是乙個可變物件 比如字典或者列表 的引用,就能修改物件的原始值 相當於通過 傳引用 來傳遞物件。如果函式收到的是乙個不可變物件 比如數字 字元或者元組 的引...