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]
下記の例では、リストListの内容は上書きされ、valの内容は保持されたままです。
この挙動はC言語などの配列 (ポインタ相当)、あるいはPerlの無名配列と同じです。
sample.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
def func(val,L):
L[0] = val
val = 1024
val = 512
List = [128,256];
func(val,List)
print val, List
出力例
$ python sample.py
512 [512, 256]
スライシングを使用してコピーを生成するなどして回避できます。
sample.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
def func(val,L):
L[0] = val
val = 1024
val = 512
List = [128,256];
func(val,List[:])
print val, List
出力例
$ python sample.py
512 [128, 256]