【python】copyの浅いレプリケーションとdeepcopyの深いレプリケーション、辞書タイプのcopy、および「=」の詳細

3354 ワード

copy()とdeepcopy()、変数の付与については、何気なく使用するとエラーが発生し、このエラーは隠れていて、論理的にバグが見えにくい.したがって、copyとdeepcopyを使用して処理を詳細に宣言したほうがいいです.では、この2つのコピーの違いはどこにあるのか、まず次の2つの結論を見てみましょう.次に、この2つの結論を持って次の分析を行うことができます.
  • の一般的な意味の複製は深い複製であり、複製されたオブジェクトが独立した新しい個体として完全に再複製される.したがって、既存のコピーされたオブジェクトを変更することは、コピーされた新しいオブジェクトに影響を与えません.
  • でshallow copyは独立したオブジェクトが単独で存在することはありません.彼は既存のデータブロックに新しいラベルを付けるだけなので、そのうちの1つのラベルが変更されると、データブロックが変化し、別のラベルも変化します.これは私たちの普通の意味でのレプリケーションとは違います.

  • つまり通常、私たちが望んでいるレプリケーションはdeepcopyで深くレプリケーションされますが、浅いレプリケーションshadowcopyの存在意義はどこにあるのでしょうか.詳しく説明します.
    1、copy()とdeepcopy()
    簡単なobjectについてはshallow copyとdeep copyで区別はありません.複雑なobject、例えばlistにlistがセットされている場合、shallow copyのサブlistは、元のobjectから本当に「独立」していません.つまり、元objectのサブリストの要素を変えると、copyが一緒に変わります.これは私たちが直感的に「複製」に対する理解とは違います.
    import copy
    from copy import deepcopy
    origin = [1,2,[3,4]]
    # origin       ,1,2,[3,4]
    copy1 = copy.copy(origin)
    copy2 = deepcopy(origin)
    print(copy1 == copy2)   # True
    print(copy1 is copy2)   # False
    # copy1  copy2     ,        object
    origin[2][0] = "hey!"
    print(origin)   # [1, 2, ['hey!', 4]]
    print(copy1)    # [1, 2, ['hey!', 4]]
    print(copy2)    # [1, 2, [3, 4]]
    

    copy 1、つまりshallowcopyがoriginに従って変わったことがわかります.copy 2、つまりdeepcopyは変わっていません.deepcopyは私たちの「複製」に対する直感的な定義にもっと合っていることがわかります.いったん複製されたら、独立しているはずです.文字通りの「copy」がほしいなら、deepcopyをそのまま使えばいいです.
    2、辞書データ型のcopy
    辞書データ型のcopy関数は,単純な値が置換されると,元の辞書とコピーされた辞書との間には互いに影響しないが,追加,削除などの修正操作の場合,両者の間には相互に影響する.上記の付与操作に相当し、元のオブジェクトの上にラベルを貼り付ける.
  • 値置換(一級object、親オブジェクト)、辞書配列タイプのcopy関数複製の相互影響
  • a = {
        "name":["An","Assan"]
    }
    b = a.copy()
    
    a["name"] = ["An"]
    
    print(a)
    print(b)
    """
    {'name': ['An']}
    {'name': ['An', 'Assan']}
    
    del a['name']
    print(a)
    print(b)
    """
    {}
    {'name': ['An', 'Assan']}
    """
    
  • 値修正(二次object,サブオブジェクト)、辞書配列タイプのcopy関数複製の相互影響
  • a = {
        "name":["An","Assan"]
    }
    b = a.copy()
    
    a["name"].append("Hunter")
    
    print(a)
    print(b)
    """
    {'name': ['An', 'Assan', 'Hunter']}
    {'name': ['An', 'Assan', 'Hunter']}
    
    a['name'].remove('An')
    """
    {'name': ['Assan', 'Hunter']}
    {'name': ['Assan', 'Hunter']}
    """
    

    元のコピーされた値を変更しない場合は、deepcopyを使用して、コピー前後の2つの変数を独立させる必要があります.
    a = {
        "name":["An","Assan"]
    }
    b = deepcopy(a)
    a["name"].append("Hunter")
    print(a)
    print(b)
    """
    {'name': ['An', 'Assan', 'Hunter']}
    {'name': ['An', 'Assan']}
    """
    

    3、「=」は一般的な意味のコピー、浅いコピー
    list1 = [1,2,[3,4]]
    list2 = list1
    list1.append(5)
    print(list1)
    # [1, 2, [3, 4], 5]
    print(list2)
    # [1, 2, [3, 4], 5]
    list1[2].remove(3)
    print(list1)
    # [1, 2, [4], 5]
    print(list2)
    # [1, 2, [4], 5]
    

    4、リストスライスは深いコピーに等しい
    list1 = [1,2,[3,4]]
    list2 = list1[:]
    list1.append(5)
    print(list1)
    # [1, 2, [3, 4], 5]
    print(list2)
    # [1, 2, [3, 4]]
    list1[2].remove(3)
    print(list1)
    # [1, 2, [4], 5]
    print(list2)
    # [1, 2, [4]]