ホームページ >バックエンド開発 >Python チュートリアル >Pythonにおける深いコピーと浅いコピーの用途と注意点は何ですか?

Pythonにおける深いコピーと浅いコピーの用途と注意点は何ですか?

王林
王林転載
2023-05-31 08:05:351859ブラウズ

    1. Python の深いコピーと浅いコピーの概念

    Python では、代入操作が実行されると、オブジェクトへの参照が実際に変数に代入されます。したがって、これら 2 つの変数は同じオブジェクトを指します。オブジェクトをコピーする必要がある場合は、コピー操作を使用する必要があります。

    浅いコピーとは、新しいオブジェクトを作成し、元のオブジェクトの参照を新しいオブジェクトにコピーすることを指します。新しいオブジェクトは元のオブジェクトと同じメモリ アドレスを共有するため、一方のオブジェクトの値が変更されると、もう一方のオブジェクトの値も影響を受けます。浅いコピーでは、オブジェクトのコンテンツの 1 つのレイヤーのみがコピーされます。

    元のオブジェクトとそのサブオブジェクトのすべての内容を再帰的にコピーして、新しいオブジェクトを作成します。これがディープ コピーです。新しいオブジェクトは元のオブジェクトとメモリ アドレスを共有せず、完全に独立しているため、一方のオブジェクトの値を変更しても、もう一方のオブジェクトの値には影響しません。

    2. Python の深いコピーと浅いコピーの使用シナリオ

    浅いコピーは、リスト、タプル、辞書などの単純なオブジェクトのコピーなど、オブジェクト階層が浅い状況に適しています。オブジェクトの要素がすべて不変型である場合は、浅いコピーを使用してオブジェクトをコピーできます。

    ネストされたリストのリストやネストされた辞書の辞書など、オブジェクト階層が複雑な場合は、ディープ コピーが適切な選択です。オブジェクトの要素に変更可能なオブジェクトが含まれている場合、コピーが必要な場合はディープ コピーを使用する必要があります。

    3. Python のディープ コピーとシャロー コピーに関する注意事項

    • 不変オブジェクト (数値、文字列、タプルなど) の場合、シャロー コピーとディープ コピーは同じ 。

    • 浅いコピーでは、可変オブジェクト (リストや辞書など) のコンテンツの 1 レベルのみがコピーされますが、可変オブジェクトに含まれるサブオブジェクトは再帰的にコピーされません。サブオブジェクトを再帰的にコピーする必要がある場合は、ディープ コピーを使用する必要があります。

    • オブジェクトに循環参照が含まれている場合、ディープ コピーを試行すると無限再帰が発生し、プログラムがクラッシュする可能性があります。したがって、ディープ コピーを使用する場合は、循環参照を含むオブジェクトに注意する必要があります。

    • ディープ コピーを使用する場合、オブジェクトの階層構造が複雑な場合、パフォーマンス上の問題が発生する可能性があるため、ディープ コピーの使用には注意が必要です。

    4. Python の深いコピーと浅いコピーの実装

    Python では、深いコピーと浅いコピーを実装する 2 つの方法 (copy モジュールを使用する方法と pickle モジュールを使用する方法) を提供します。

    1. コピー モジュールを使用する

    Python のコピー モジュールには、シャロー コピーとディープ コピーという 2 つの機能があります。

    浅いコピーは、copy() 関数を使用して実装できます。例:

    import copy
    
    a = [1, 2, 3]
    b = copy.copy(a)
    print(b)  # [1, 2, 3]

    ディープ コピーは、deepcopy() 関数を使用して実装できます。例:

    import copy
    
    a = [[1, 2], [3, 4]]
    b = copy.deepcopy(a)
    print(b)  # [[1, 2], [3, 4]]

    2. pickle モジュールを使用します

    Python の pickle モジュールは、Python オブジェクトをバイト ストリームにシリアル化し、バイト ストリームを Python オブジェクトに逆シリアル化できます。 pickle モジュールを通じてディープコピーを実現できます。

    ディープ コピーは、pickle モジュールを使用して実装できます。例:

    import pickle
    
    a = [[1, 2], [3, 4]]
    b = pickle.loads(pickle.dumps(a))
    print(b)  # [[1, 2], [3, 4]]

    pickle モジュールを使用してディープ コピーを実装すると、パフォーマンスの問題が発生する可能性があるため、注意が必要です。使用するとき。

    5. 概要

    Python のディープ コピーとシャロー コピーは非常に実用的な概念であり、ディープ コピーとシャロー コピーの使用シナリオと注意事項をマスターすると、オブジェクトのコピーと変更をより適切に処理できるようになります。深いコピーと浅いコピーを実装する場合、Python の copy モジュールと pickle モジュールを使用し、特定の状況に応じて適切な方法を選択できます。なお、ディープコピーを使用する場合、オブジェクト階層が複雑な場合、パフォーマンス上の問題が発生する可能性があるため、ディープコピーの使用には注意が必要です。開発プロセス中は、可能な限り浅いコピーを使用するように努め、必要な場合にのみ深いコピーの使用を検討する必要があります。

    さらに、ディープ コピーを使用する場合、オブジェクトの要素に可変オブジェクトが含まれる場合、循環参照を含むオブジェクトの処理に注意する必要があります。そうしないと、無限再帰に陥り、プログラムがクラッシュする可能性があります。

    つまり、深いコピーと浅いコピーは Python において非常に重要な概念です。深いコピーと浅いコピーの使用法と注意事項をマスターすることで、オブジェクトのコピーと変更をより適切に処理し、パフォーマンスと保守性を向上させることができます。プログラム。

    最後に、深いコピーと浅いコピーの使用方法を示す実際の例を見てみましょう。

    リストと辞書を含む複雑なオブジェクトがあり、それをコピーして変更する必要があるとします。以下はサンプル コードです。

    import copy
    
    # 定义一个包含列表和字典的复杂对象
    a = {
        "name": "Tom",
        "age": 18,
        "scores": [80, 90, 95],
        "info": {
            "address": "Beijing",
            "phone": "1234567890"
        }
    }
    
    # 浅拷贝
    b = copy.copy(a)
    b["name"] = "Jerry"
    b["scores"].append(100)
    b["info"]["address"] = "Shanghai"
    print(a)  # {'name': 'Tom', 'age': 18, 'scores': [80, 90, 95, 100], 'info': {'address': 'Shanghai', 'phone': '1234567890'}}
    print(b)  # {'name': 'Jerry', 'age': 18, 'scores': [80, 90, 95, 100], 'info': {'address': 'Shanghai', 'phone': '1234567890'}}
    
    # 深拷贝
    c = copy.deepcopy(a)
    c["name"] = "Lucy"
    c["scores"].append(99)
    c["info"]["address"] = "Guangzhou"
    print(a)  # {'name': 'Tom', 'age': 18, 'scores': [80, 90, 95, 100], 'info': {'address': 'Shanghai', 'phone': '1234567890'}}
    print(c)  # {'name': 'Lucy', 'age': 18, 'scores': [80, 90, 95, 100, 99], 'info': {'address': 'Guangzhou', 'phone': '1234567890'}}

    上記のサンプル コードでは、まずリストと辞書を含む複合オブジェクト a を定義し、次にシャロー コピーとディープ コピーを使用してコピーおよび変更します。

    copy() 関数を呼び出してオブジェクト a の浅いコピーを作成すると、新しいオブジェクト b を取得できます。次に、新しいオブジェクト b の名前、スコア、情報のアドレス属性を変更し、元のオブジェクト a と新しいオブジェクト b の値を出力しました。元のオブジェクト a の値は変化していませんが、新しいオブジェクト b の値が変化していることがわかります。

    deepcopy() 関数を使用してオブジェクト a をディープコピーすると、新しいオブジェクト c を取得できます。次に、新しいオブジェクト c の名前、スコア、情報のアドレス属性を変更し、元のオブジェクト a と新しいオブジェクト c の値を出力しました。元のオブジェクト a の値は変化していませんが、新しいオブジェクト c の値が変化していることがわかります。

    上記のサンプル コードを通じて、深いコピーと浅いコピーは複雑なオブジェクトを扱うときに非常に便利で、オブジェクトのコピーと変更をより適切に処理するのに役立つことがわかります。実際の開発では、特定のシナリオに基づいて適切なコピー方法を選択し、可能な限り浅いコピーを使用し、必要な場合にのみ深いコピーを使用する必要があります。

    以上がPythonにおける深いコピーと浅いコピーの用途と注意点は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明:
    この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。