Pythonの辞書(dict)は本当に可変?ミュータブルな挙動を徹底解説
はい、Pythonの辞書(dict)は可変(ミュータブル)です。キーに対する値を変更しても、新しい辞書オブジェクトが生成されることはありません。代わりに、既存の辞書オブジェクトがその場(in-place)で更新されます。
具体例
a = {'foo': 1, 'bar': 12}
b = a
b['foo'] = 20
print(a)
print(b)
出力結果
このコードを実行すると、次のような出力が得られます。
{'foo': 20, 'bar': 12}
{'foo': 20, 'bar': 12}
なぜ両方の辞書が変わるのか?
b = a という代入では、辞書の中身がコピーされるわけではなく、同じオブジェクトへの参照が変数 b に渡されます。そのため、b を通じて値を変更すると、a も同一のオブジェクトを指しているため、a の内容も同時に変化するのです。
これはPythonにおける重要な挙動であり、意図せずバグを生む原因にもなり得ます。特にリストや辞書などのミュータブルなオブジェクトを扱う際には注意が必要です。
独立したコピーを作成したい場合
元の辞書に影響を与えずに別の辞書として扱いたい場合は、copy() メソッド(浅いコピー)や copy.deepcopy()(深いコピー)を使用します。
import copy
a = {'foo': 1, 'bar': 12}
b = copy.deepcopy(a)
b['foo'] = 20
print(a) # {'foo': 1, 'bar': 12}
print(b) # {'foo': 20, 'bar': 12}
このように deepcopy() を使えば、b への変更が a に影響しない、完全に独立した辞書を作成できます。
-
Pythonでタプルが不変(イミュータブル)である理由とは?
Pythonのタプルが不変(イミュータブル)である理由は、主に以下の5つのポイントにあります。 1. 順序の維持 タプルは、Pythonにおいて「順序」を表現するためのデータ構造として設計されています。例えば、データベースからタプルのリスト形式でデータを取得する場合、各タプルは取得したフィールドの順序どおりに並んでいます。不変であることで、この順序が意図せず書き換えられる心配がありません。 2. コピー効率 不変オブジェクトの場合、実体を丸ごとコピーする代わりに、エイリアス(同じオブジェクトへの参照の別名)を作成するだけで済みます。変数を参照として束縛するだけでよいため、メモリ消費と処理時
-
Pythonのreturnステートメントとは?print()との違いをわかりやすく解説
Pythonのprint()関数は、文字列や数値をコンソールに出力(表示)するための関数です。一方、returnステートメントは、関数が呼び出されたときにその戻り値を画面に表示するものではありません。 returnステートメントの主な役割は次の2つです。 関数内で処理した結果(値)を、呼び出し元へ返すこと returnが実行された時点で、たとえそれが関数の最後の文でなくても、関数を即座に終了させること 値を返す関数は「実りある関数(fruitful function)」と呼ばれることがあります。また、多くの他のプログラミング言語では、値を返さない関数は「プロシージャ(procedure)」