LoginSignup
0
1

More than 3 years have passed since last update.

Pythonの代入時の挙動を確認する

Last updated at Posted at 2019-12-16

まとめ

  • 変数とはオブジェクトを参照するための名前で、変数の参照するオブジェクトはid(hoge)で確認できる
  • y = x の意味は、代入先の変数yが参照するオブジェクトを、代入元の変数xが参照するオブジェクトにする、ということ
  • xがintであろうとlistであろうとtupleであろうと全ての変数で共通の動作である
  • 参照渡しとは変数そのものの参照を渡すことなので、いわゆる参照渡しはできない
  • リストの要素を代入した時も同様であるが、リスト自体の参照先は変更されないため、一見参照渡しのような挙動にみえる

代入するときの挙動確認

intの変数を代入する

  • 変数aの参照先が代入によって変数bの参照先に変わる
a = 1
b = 2
print("a:",a,"b:",b)
print("id_a:", id(a), "id_b:", id(b))
a = b   # aのidはbのidに置き換わる
print("a:",a,"b:",b)
print("id_a:", id(a), "id_b:", id(b))

結果

a: 1 b: 2
id_a: 93893417024192 id_b: 93893417024224
a: 2 b: 2
id_a: 93893417024224 id_b: 93893417024224

bに新たな変数3を代入する

  • bに3を代入すると、bは3という新たなオブジェクトを参照する
  • このときaは元の参照先のままなので、変更の影響は受けない
b = 3   # bのidは3のidに置き換わる, aのidはそのまま
print("a:",a,"b:",b)
print("id_a:", id(a), "id_b:", id(b))

結果

a: 2 b: 3
id_a: 93893417024224 id_b: 93893417024256

変数がlistの場合

  • intの場合と同じ
a = [1,1]
b = [2,2]
print("a:",a,"b:",b)
print("id_a:", id(a), "id_b:", id(b))
a = b  # aのidはbのidに置き換わる
print("a:",a,"b:",b)
print("id_a:", id(a), "id_b:", id(b))
b = [3,3]  # bのidは3のidに置き換わる, aのidはそのまま
print("a:",a,"b:",b)
print("id_a:", id(a), "id_b:", id(b))

結果

a: [1, 1] b: [2, 2]
id_a: 140361960710984 id_b: 140361960208392
a: [2, 2] b: [2, 2]
id_a: 140361960208392 id_b: 140361960208392
a: [2, 2] b: [3, 3]
id_a: 140361960208392 id_b: 140361960256584

listの要素への代入

  • リストの要素に対して代入をするときは、リストの要素の参照先は変わるが、リストそのものの参照先は変わらない
  • aとbの参照先は同じオブジェクトのままなので、aはbの変更の影響を受ける
  • リスト要素の参照先が変わっていることから、参照渡しをしている訳ではないことが分かる
a = [1,1]
b = [2,2]
print("a:",a,"b:",b)
print("id_a:", id(a), "id_b:", id(b))
print("id_a[0]:", id(a[0]), "id_b[0]:", id(b[0]))
a = b  # aのidはbのidに置き換わる
print("a:",a,"b:",b)
print("id_a:", id(a), "id_b:", id(b))
print("id_a[0]:", id(a[0]), "id_b[0]:", id(b[0]))
b[0] = 3  # b[0]のidは3のidに置き換わると同時にa[0]のidも3のidに置き換わる, aとbのidは元のまま
print("a:",a,"b:",b)
print("id_a:", id(a), "id_b:", id(b))
print("id_a[0]:", id(a[0]), "id_b[0]:", id(b[0]))

結果

a: [1, 1] b: [2, 2]
id_a: 140361961620360 id_b: 140361958272904
id_a[0]: 93893417024192 id_b[0]: 93893417024224
a: [2, 2] b: [2, 2]
id_a: 140361958272904 id_b: 140361958272904
id_a[0]: 93893417024224 id_b[0]: 93893417024224
a: [3, 2] b: [3, 2]
id_a: 140361958272904 id_b: 140361958272904
id_a[0]: 93893417024256 id_b[0]: 93893417024256

dict型の要素の代入

dict内部に直接代入する場合、dictのidは変わらず、代入したdict要素のidが置き換わる。
このとき、dictのidを共有している変数があれば、dictのidが不変なため、dict要素が変更されている。

a = {0:1}
b = {0:2}
print("a:",a,"b:",b)
print("id_a:", id(a), "id_b:", id(b))
print("id_a[0]:", id(a[0]), "id_b[0]:", id(b[0]))
a = b  # aのidはbのidに置き換わる
print("a:",a,"b:",b)
print("id_a:", id(a), "id_b:", id(b))
print("id_a[0]:", id(a[0]), "id_b[0]:", id(b[0]))
b[0] = 3  # b[0]のidは3のidに置き換わると同時にa[0]のidも3のidに置き換わる, aとbのidは元のまま
print("a:",a,"b:",b)
print("id_a:", id(a), "id_b:", id(b))
print("id_a[0]:", id(a[0]), "id_b[0]:", id(b[0]))

結果

a: {0: 1} b: {0: 2}
id_a: 140362018772456 id_b: 140361986516168
id_a[0]: 93893417024192 id_b[0]: 93893417024224
a: {0: 2} b: {0: 2}
id_a: 140361986516168 id_b: 140361986516168
id_a[0]: 93893417024224 id_b[0]: 93893417024224
a: {0: 3} b: {0: 3}
id_a: 140361986516168 id_b: 140361986516168
id_a[0]: 93893417024256 id_b[0]: 93893417024256

参考資料:
プログラミング FAQ — Python 3.8.1rc1 ドキュメント
C#でわかる値渡し、参照渡し - Qiita
なぜ、Java、JavaScript、Python、Ruby等で「参照渡し」の言葉を使うべきではないのか? - Qiita
もう参照渡しとは言わせない - Qiita

0
1
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1