PY => 深拷貝/淺拷貝多種語法解析

列表爲例(可變類型容器),直接上代碼:

第一種:app

a = [[1,2], [3,4]]
[_.append(666) for _ in a]        # 原生列表  (for 也是同樣的,圖個方便,用了推導式)
print(a)

>> [[1, 2, 666], [3, 4, 666]]

第二種:code

a = [[1,2], [3,4]]
[_.append(666) for _ in a[:]]     # 新增操做: 對整個列表切片自爆
print(a)

>> [[1, 2, 666], [3, 4, 666]]

第三種:入門

a = [[1,2], [3,4]]
[_.append(666) for _ in copy.copy(a)]      # 新增操做: 對整個列表使用淺拷貝API
print(a)

>> [[1, 2, 666], [3, 4, 666]]

------------------ 分割線-------------------------

第四種:import

a = [[1,2], [3,4]]
[_.append(666) for _ in copy.deepcopy(a)]      # 新增操做: 整個列表使用深拷貝API
print(a)

>> [[1, 2], [3, 4]]

第五種:(注意 和 第二種 對比)容器

a = [[1,2], [3,4]]
[_[:].append(666) for _ in a]      # 新增操做:對即將操做的子列表切片自爆
print(a)

>> [[1, 2], [3, 4]]

第六種:(注意 和 第三種 對比)基礎

a = [[1,2], [3,4]]
[copy.copy(_).append(666) for _ in a]   # 新增操做:對即將操做的子列表 使用淺拷貝API
print(a)

>> [[1, 2], [3, 4]]

提醒0

多級容器需謹慎 (雖然多級 純 元組是不可變類型,你想弄也弄不動它~~~)
可是這種狀況,你仍是須要注意:im

a = ([1,2], [3,4])
# 裏面的列表依然是可變的, 這算是剛入門的基礎。但還應該留意

提醒一

除了 deepcopy, 其餘操做都是淺拷貝。
若是你喜歡使用 [::] , [:] 這種切片拷貝, 那麼更應該注意一下上述案例問題。copy

提醒二

也許你看上述代碼很通常。甚至沒有任何感受。
可是當你把子列表看成中間值(任意操做變換), 再提醒一次 ===> 做爲 中間值(或者說臨時值)使用時。
你的BUG可能在向你招手!co

附贈:求 子集 案例

import copy
def f(sub):
    temp_list = [[]]

    for x in sub:
        for y in copy.deepcopy(temp_list):
            y.append(x)
            temp_list.append(y)

    return temp_list

print(f(list(range(4))))
相關文章
相關標籤/搜索