Pythonでは複数の変数に一括して値を代入することができます.
a = b = 1 print(f"{a}, {b}. id={id(a)}, id={id(b)}") b = 2 print(f"{a}, {b}. id={id(a)}, id={id(b)}")
これをPython3.8で実行すると,
1, 1. id=4347452064, id=4347452064 1, 2. id=4347452064, id=4347452096
となります.a = b = 1
で,変数aとbに同じidのint 1が代入されています.b = 2
では,変数bに別のidのint 2が代入されるので,aとbは異なる値となります.
このようにミュータブルな変数では直感的にうまく動作しますが,イミュータブルな変数では少し注意が必要です.
a = b = ["apple", "banana", "orange"] print(f"{a}, {b}. id={id(a)}, id={id(b)}") b[1] = "mango" print(f"{a}, {b}. id={id(a)}, id={id(b)}")
これを実行すると,
['apple', 'banana', 'orange'], ['apple', 'banana', 'orange']. id=140672811873216, id=140672811873216 ['apple', 'mango', 'orange'], ['apple', 'mango', 'orange']. id=140672811873216, id=140672811873216
となります.a = b = ["apple", "banana", "orange"]
では変数aとbに代入されたlistは同じオブジェクトなので,b[1] = "mango"
で変数bの要素を変更すると,オブジェクトそのものが変更されます.一見,変数aも変更されたように見えるのです.
この動作は便利な場合もありますが,今回のように一括代入する場合は不便なので,素直に深いコピーをします.
a = ["apple", "banana", "orange"] b = a[:] print(f"{a}, {b}. id={id(a)}, id={id(b)}") b[1] = "mango" print(f"{a}, {b}. id={id(a)}, id={id(b)}")
これを実行すると,
['apple', 'banana', 'orange'], ['apple', 'banana', 'orange']. id=140706788993536, id=140706785735872 ['apple', 'banana', 'orange'], ['apple', 'mango', 'orange']. id=140706788993536, id=140706785735872
となり,期待通りに動作します.
このあたりの詳細は,3. データモデル — Python 3.8.3 ドキュメントに記載されています.
c = ; d = とすると、 c と d はそれぞれ二つの異なった、互いに一意な、新たに作成された空のリストを参照することが保証されています。 (c = d = [] とすると、 c と d の両方に同じオブジェクトを代入します)