リファレンス共有
Rubyなどと同様に、代入ステートメントではオブジェクトは生成されずにリファレンスがコピーされるだけです。
そのため、ある変数に格納されているリファレンスを用いてオブジェクトの値を変更すると、別の変数に格納されているリファレンスから参照したときにも値が変更されていることになります。
sample.py
L1 = [1,2]
L2 = L1
L1 += [3,4]
print L2
出力例
$ python sample.py
[1, 2, 3, 4]
これを回避するためには、新たなオブジェクトが生成されるように工夫する必要があります。
sample.py
L1 = [1,2]
L2 = L1
L1 = L1 + [3,4] # 新たなオブジェクトを生成し、そのリファレンスを代入
print L2
出力例
$ python sample.py
[1, 2]
関数の引数で生じる同様の現象
下記の例では、リスト mylist の内容は上書きされ myval の内容は保持されたままです。
この挙動はC言語などの配列 (ポインタ相当)、あるいはPerlの無名配列と同じです。
sample.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
def func(myval,L):
L[0] = myval
myval = 1024
myval = 512
mylist = [128,256];
func(myval, mylist)
print myval, mylist
出力例
$ python sample.py
512 [512, 256]
スライシングを使用してコピーを生成するなどして回避できます。
sample.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
def func(myval,L):
L[0] = myval
myval = 1024
myval = 512
mylist = [128,256];
func(myval,mylist[:])
print myval, mylist
出力例
$ python sample.py
512 [128, 256]
0
プログラミング教育者。ScratchやPythonを教えています。
記事の執筆者にステッカーを贈る
有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。
さらに詳しく →Feedbacks
ログインするとコメントを投稿できます。


