Pythonの辞書(dict)をコピーする方法と注意点まとめ

ここでは、Pythonで辞書をコピーする方法についてまとめています。

具体的には、

  • ミュータブルなオブジェクトである辞書を代入でコピーすることの弊害
  • copy()メソッドを使った辞書のコピー方法
  • dict.fromkeys()関数を使って、リストのキーだけをコピーする方法

の3つを解説しています。

ぜひ、参考にして頂ければ嬉しく思います。

目次

1. 辞書をコピーしたい時は代入は使わないこと

Pythonで既存の辞書をコピーして、新しい辞書を作る時にありがちなミスが、「new_dict = old_dict」というように、「新しい辞書に既存の辞書を代入してしまう」というものです。

辞書はイミュータブルなオブジェクトです。そのため、この方法では、新しくコピーした(つもり)の辞書に変更を加えると、元のリストにまで同じ変更が加えられてしまうという問題が起きます。

以下の例をご覧ください。

In [1]:
#dict1を作ります。
dict1 = {"red":1, "blue":2, "yellow":3}
 
#dict2にdict1を代入します。
dict2 = dict1
 
#dict2の値を変更します。
dict2["red"] = 4
 
#dict2を確認しましょう。
dict2
Out[1]:
{'blue': 2, 'red': 4, 'yellow': 3}

一見問題ないように見えますが、実は、このとき元の辞書(dict1)も変更されてしまっています。

In [2]:
#この時、辞書1(dict1)にも変更が反映されてしまいます。
dict1
Out[2]:
{'blue': 2, 'red': 4, 'yellow': 3}

なぜ、このようなことが起きてしまうのでしょうか?

それは、dict1と、それを代入して作ったdict2は、同一オブジェクトとなり、一方に加えた変更は、他方にも影響してしまうからです。ミュータブルなオブジェクトには、常にこの問題が付きまといますので、辞書やリストは、新しい変数に代入してコピーするという癖をつけないようにした方がよいです。

ミュータブルなオブジェクトとイミュータブルなオブジェクトの違いと、双方を扱うときの注意点は、「Pythonのリストとタプルの違いと使い分け」でも、リストとタプルを比較して解説しています。併せてご覧いただくと、理解が深まるでしょう。

このような問題を防ぐためには、ミュータブルなオブジェクトをコピーする時は、copy()メソッドを使うことを癖づけると良いでしょう。

2. 辞書のコピーにはcopy()メソッドを使う

copy()メソッドで作った新しい辞書は、元となった辞書と別のオブジェクトになります。そのため、上記のような問題は起こりません。次のように書きます。

In [0]:
新しい辞書 = コピー元の辞書.copy()

引数には特に何も入力する必要はありません。実際に見てみましょう。

In [1]:
#辞書1(dict1)を作ります。
dict1 = {"red":1, "blue":2, "yellow":3}
 
#copy()メソッドで辞書を作ります。
dict2 = dict1.copy()
 
#dict2の値を変更します。
dict2["red"] = 4
 
#dict2を確認しましょう。
dict2
Out[1]:
{'blue': 2, 'red': 4, 'yellow': 3}

この時、dict1 と dict2 は別のオブジェクトなので、元の辞書である dict1 には影響はありません。

In [2]:
#dict1に変更は反映されません。
dict1
Out[2]:
{'blue': 2, 'red': 1, 'yellow': 3}

せっかく沢山書いたコードが、辞書のミュータビリティが原因で動かないとなると、その原因を特定して修正する手間は、かなりのものになります。そのような状況を防ぐためにも、ミュータブルなオブジェクトである辞書をコピーしたい時は、copy()メソッドを使いましょう。

3. ある辞書のキーだけコピーするにはdict.fromkeys()を使う

ある辞書のキーだけをコピーしたい場合は、dict.fromkeys()関数が便利です。次のように書きます。

In [0]:
新しい辞書 = dict.fromkeys(辞書, 値)

実際に見てみましょう。

In [1]:
#dict1を作ります。
dict1 = {"red":1, "blue":2, "yellow":3}
 
#dict.fromkeys()でキーをコピーしたdict2を作ります。
dict2 = dict.fromkeys(dict1, 0)
 
#確認しましょう。
dict2
Out[1]:
{'blue': 0, 'red': 0, 'yellow': 0}

値を指定しない場合は、キーの値は空(None)になります。

In [1]:
#辞書1(dict1)を作ります。
dict1 = {"red":1, "blue":2, "yellow":3}
 
#dict.fromkeys()でキーをコピーした辞書2(dict2)を作ります。
dict2 = dict.fromkeys(dict1)
 
#確認しましょう。
dict2
Out[1]:
{'blue': None, 'red': None, 'yellow': None}

知っておくと便利なので、頭の片隅に入れておいて頂ければと思います。

4. まとめ

ミュータブルなオブジェクトである辞書やリストを、コピーする際は、代入による方法は避けて、copy()メソッドを使うように癖づけておきましょう。

また、ミュータブルなオブジェクトと、イミュータブルなオブジェクトの違いを、しっかりと理解しておけば、様々なところで最適な選択をできるようになると思います。コードを書きながら、少しずつ理解を深められるように、意識できればとても良いと思います。

なお辞書の場合はcopy()メソッドで問題ありませんが、リストの場合は、「浅いコピー」と「深いコピー」という概念を知っておかなければ、後で大変な思いをする可能性があります。

Pythonのリストのコピー方法と注意点」でしっかりと確認しておきましょう。

Python初心者におすすめのプログラミングスクール

「未経験からでもPythonを学べるプログラミングスクールを探しているけど、色々ありすぎてわからない」なら、次の3つのプログラミングスクールから選んでおけば間違いはありません。

Aidemy Premium:全くの初心者ができるだけ効率よく短期間で実務的に活躍できるAI人材になることを目的とした講座。キャリアカウンセリングや転職エージェントの紹介などの転職支援も充実しており、受講者の転職成功率が高い。

AIジョブカレPythonの基本をおさえた人が、実際に機械学習やディープラーニングを活用できるようになるための講座。転職補償型があるなどキャリア支援の内容が非常に手厚く、講師の質も最高クラス。コスパ最高。Python初心者用の対策講座もある。

データミックスプログラミング経験者のビジネスマンが、更なるキャリアアップのためにデータの処理方法を学んでデータサイエンティストになるための講座。転職だけでなく起業やフリーランスとして独立する人も多い。Python初心者用の対策講座もある。

特に、あなたが以下のような目標を持っているなら、この中から選んでおけば間違いはないでしょう。

・未経験からPythonエンジニアとして就職・転職したい
・AIエンジニアやデータサイエンティストとしてキャリアアップしたい
・起業やフリーランスを視野に入れたい

理由は「Python初心者のためのおすすめプログラミングスクール3選」で解説しています。



よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメント一覧 (1件)

  • >1. 辞書をコピーしたい時は代入は使わないこと
    にて、
    >辞書はイミュータブルなオブジェクトです。

    となっています。ミュータブルの間違いでしょうか。

    また、本記事で示されている例であれば問題になりませんが、辞書の中にミュータブルオブジェクトを含めた場合、copy()だけでは完全にコピーできません。リストだけでなく辞書でも深いコピーを使う必要があります。

    問題になる例:
    dict1 = {“x”:[1,2,3]}
    dict2 = dict1.copy()
    dict2[“x”][0] = 100
    print(dict1[“x”]) # [100,2,3]
    print(dict2[“x”]) # [100,2,3]

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

目次
閉じる