なんということもない話なのですが、
これで困ったことがなかったので改めて勉強しなおしたという話です。
今更ではありますが、pythonでは何かを代入すると値ではなく参照が渡されます。
a = 1
b = a
print(id(a))
print(id(b))
>1928654608
>1928654608
整数型の場合、bに別の値を代入するとbのみ新しいアドレスに参照先が切り替わります。
元のaについては変更を行いません。
b = 334
print(a)
print(b)
>1
>334
しかし、リストの場合は勝手が違っています。
a = [1, 2, 3, 4]
b = a
print(a)
print(b)
>[1, 2, 3, 4]
>[1, 2, 3, 4]
b.pop(1)
print(a)
print(b)
>[1, 3, 4]
>[1, 3, 4]
bにリストaを代入し、popでbから要素を削除すると直接変更していないaの内容も変わっています。
参照先もそのままです。
print(id(a))
print(id(b))
>2277581359240
>2277581359240
「aの元の情報を保持したままbに破壊的な操作を加えたい」みたいな場合には以下のように、
スライスを使ってコピーを生成するのが手軽です。
a_ =[1, 2, 3, 4]
c = a_[:]
c.pop(1)
print(a_)
print(c)
>[1, 2, 3, 4]
>[1, 3, 4]
(2016/7/27追記)list()とかcopyモジュールを使ってもできるという意見をもらったので試しました。
a = [1, 2, 3, 4]
b = list(a)
b.pop(1)
print(a)
print(b)
>[1, 2, 3, 4]
>[1, 3, 4]
import copy
a = [1, 2, 3, 4]
c = copy.copy(a)
c.pop(1)
print(a)
print(c)
>[1, 2, 3, 4]
>[1, 3, 4]
やったぜ。