概要
「Head First Python 第2版」を進めていった中で考えたことの記録です。
Head First Python 第2版 ―頭とからだで覚えるPythonの基本
- 作者:Paul Barry
- 発売日: 2018/03/24
- メディア: 単行本(ソフトカバー)
call by sharing
first = [1, 2, 3, 4, 5] print(first) # => [1, 2, 3, 4, 5] second = first print(second) # => [1, 2, 3, 4, 5] print(id(first)) # => 2915364366464 ※一例 print(id(second)) # => 2915364366464 ※一例
上記コードにおいて注目すべきポイントは、「id(second)
の値とid(third)
の値が同じである」という点です。
Pythonの代入演算子を変数a = 変数b
という形で使用した場合、「変数aが指すオブジェクトの別名として変数bを定義する」という動作をします。このような評価戦略は、「call by sharing」「共有渡し」「参照の値渡し」などと呼ばれます1。
上記の例でいうところのid:2915364366464
というオブジェクトは、「最初にfirst
に代入した[1, 2, 3, 4, 5]
というリスト」を指します。second
のid
も2915364366464
です。
この状態でsecond.append(6)
を実行した場合の動作は以下のようになります。
second.append(6) print(second) # => [1, 2, 3, 4, 5, 6] print(first) # => [1, 2, 3, 4, 5, 6]
second
が指すリストもfirst
が指すリストも同一のオブジェクトなので、そこにappend()
という操作を行うと、append()
の結果はsecond
にもfirst
にも反映される、というわけです。
なお、「second
そのものがfirst
の別名とされる」わけではありません。この状態でいえば、「first
が指すオブジェクトそのものを入れ替えても、second
が指すオブジェクトはそのまま維持される2」という動作になります。
print(id(first)) # => 2915364366464 ※一例 print(id(second)) # => 2915364366464 ※一例 first = [1, 2, 3, 4, 5] print(id(first)) # => 2915364749760 ※一例 print(id(second)) # => 2915364366464 ※一例
上記コードの注目ポイントは以下です。
first = [1, 2, 3, 4, 5]
以前は、id(first)
の値とid(second)
の値が同じものであったことfirst = [1, 2, 3, 4, 5]
以降は、id(first)
の値とid(second)
の値が違うものになっていることfirst = [1, 2, 3, 4, 5]
以降も、id(second)
の値は変わらないこと
リストをコピーするには
リストをコピーするためのメソッドとして、リストにはcopy()
というメソッドが用意されています。
print(second) # => [1, 2, 3, 4, 5, 6] print(id(second)) # => 2915364366464 ※一例 third = second.copy() print(third) # => [1, 2, 3, 4, 5, 6] print(id(third)) # => 2915364744320 ※一例 third.append(7) print(third) # => [1, 2, 3, 4, 5, 6, 7] print(second) # => [1, 2, 3, 4, 5, 6] print(id(second)) # =>2915364366464 print(id(third)) # => 2915364744320
上記コードの注目ポイントは以下です。
id(second)
の値とid(third)
の値が異なることthird.append(7)
を実行した後も、second
が指すリストの内容は変わらないことid(second)
の値も変わらない
third.append(7)
を実行した後も、id(third)
の値は変わらないこと