對 "==", "is" 以及賦值、深淺拷貝的理解

== 與 is 的區別

  • == :判斷 ,比較兩個對象是否相等
  • is :判斷 地址,比較兩個引用是否指向了同一個對象(引用比較)

賦值、深拷貝、淺拷貝的區別

首先,不可變數據類型的內存都指向同一個地址,所以深拷貝和淺拷貝對於不可變數據類型而言都是無意義的。

對於不可變數據類型:

import copy

# 深拷貝
a = 'python'
b = copy.deepcopy(a)
print(a, id(a))  # python 2796288573600
print(b, id(b))  # python 2796288573600

# 淺拷貝
c = copy.copy(a)
print(a, id(a))  # python 2796288573600
print(c, id(c))  # python 2796288573600

賦值

是對原變量的完全複製,內存地址一樣,如果原來的改變,後面的也會跟着變。

x = [123, 456, 789]
y = x
print(x, id(x))  # [123, 456, 789] 1885210370632
print(y, id(y))  # [123, 456, 789] 1885210370632

x[0] = 1
print(x, id(x))  # [1, 456, 789] 1885210370632
print(y, id(y))  # [1, 456, 789] 1885210370632

深拷貝

對於可變數據類型:

import copy

a = [123, [1, 2, 3]]
b = copy.deepcopy(a)

print(a, id(a), id(a[0]), id(a[1]))  # [123, [1, 2, 3]] 2734749304648 140719688872400 2734749304584
print(b, id(b), id(b[0]), id(b[1]))  # [123, [1, 2, 3]] 2734749395720 140719688872400 2734749502728

a[1][0] = 5  # 修改嵌套列表的元素
print(a, id(a), id(a[0]), id(a[1]))  # [123, [5, 2, 3]] 2734749304648 140719688872400 2734749304584
print(b, id(b), id(b[0]), id(b[1]))  # [123, [1, 2, 3]] 2734749395720 140719688872400 2734749502728

我們可以看到,深拷貝是直接創建了一個新的對象,所以地址不同,將原對象所有的值/元素拷貝過來,而且是對其所有層次的拷貝(包括嵌套列表)

  • 將原對象的“ 值/元素 ”賦給新對象,新對象中元素的地址與原對象的 地址不同
  • 是對原對象 所有層次 的拷貝(遞歸)
  • 與原對象沒有任何關係,如果原對象發生變化,深拷貝後的新對象 不會發生改變

淺拷貝

對於可變數據類型:

import copy

a = [123, [1, 2, 3]]
b = copy.copy(a)

print(a, id(a), id(a[0]), id(a[1]))  # [123, [1, 2, 3]] 2944705742536 140719688872400 2944705742472
print(b, id(b), id(b[0]), id(b[1]))  # [123, [1, 2, 3]] 2944705837704 140719688872400 2944705742472

a[1][0] = 5  # 修改嵌套列表的元素
print(a, id(a), id(a[0]), id(a[1]))  # [123, [5, 2, 3]] 2944705742536 140719688872400 2944705742472
print(b, id(b), id(b[0]), id(b[1]))  # [123, [5, 2, 3]] 2944705837704 140719688872400 2944705742472

我們可以看到,兩個列表的元素指向同一地址,拷貝的只是原列表元素的引用。
當我們修改嵌套列表的元素時,新列表中的嵌套列表也會發生改變,這是因爲淺拷貝只拷貝了表面一層列表,而嵌套列表並沒有進行拷貝,所以修改嵌套列表之後,新列表也會變。

  • 將原對象的 引用 賦給新對象,新對象中元素的地址與原對象的 地址相同
  • 是對原對象 頂層 的拷貝(表面一層)
  • 由於只拷貝了表面一層,當原對象中的嵌套對象發生改變時,新對象也 會發生改變
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章