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

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

# 代入するときの挙動確認
## intの変数を代入する
* 変数aの参照先が代入によって変数bの参照先に変わる

```python
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は元の参照先のままなので、変更の影響は受けない

```python
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の場合と同じ

```python
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の変更の影響を受ける
* リスト要素の参照先が変わっていることから、参照渡しをしている訳ではないことが分かる

```python
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要素が変更されている。

```python
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 ドキュメント](https://docs.python.org/ja/3/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by-reference)
[C#でわかる値渡し、参照渡し - Qiita](https://qiita.com/KageShiron/items/b74d9246aad3ca0854c2)
[なぜ、Java、JavaScript、Python、Ruby等で「参照渡し」の言葉を使うべきではないのか？ - Qiita](https://qiita.com/raccy/items/59a6ac6c818918dd9651)
[もう参照渡しとは言わせない - Qiita](https://qiita.com/mdstoy/items/2ef4ada6f88341466783)