「リストを別の変数にコピーしたはずなのに、片方を変更したらもう片方まで変わってしまった…😱」
Pythonを始めたばかりの方がハマりやすい、このビックリ現象。実はPythonの変数の仕組みを理解すると、「なるほど!」と一気に納得できます。今回はこの不思議な挙動をわかりやすく解説していきます!
🔍 まず現象を確認してみよう

こんなコードを見てください。これ、実行せずに正確に答えられますか?
# リストを変数aに代入して、bにもコピー(のつもり)
a = [1, 2, 3]
b = a # aをbに代入
b.append(4) # bにだけ要素を追加したつもり…
print(a) # → どうなる?
print(b) # → どうなる?
実行結果はこうなります。
[1, 2, 3, 4]
[1, 2, 3, 4]
bを変更したのに、aまで変わってしまっています!初めて見ると「バグ?」と思いますよね。でもこれ、Pythonの仕様どおりの動作なんです。
💡 変数は「ラベル(名前)」にすぎない
ここが核心です。Pythonの変数はデータそのものを入れる箱ではなく、オブジェクトへの「参照(リファレンス)」です。
イメージとしては、こんな感じです。
- リスト
[1, 2, 3]というデータがメモリ上のどこかに存在する a = [1, 2, 3]と書くと、「a」というラベルがそのデータを指すb = aと書くと、「b」というラベルも同じデータを指すだけ
つまり、aとbは別々のリストを持っているのではなく、同じひとつのリストを2つの名前で呼んでいる状態なんです。
🛠 本当にコピーしたいときはどうする?
ポイントをまとめるとこんな感じです。リストを独立したコピーとして複製するには、以下のいずれかの方法を使います。
a = [1, 2, 3]
# 方法①:スライスでコピー
b = a[:]
# 方法②:copyメソッドでコピー
b = a.copy()
# 方法③:list()でコピー
b = list(a)
b.append(4)
print(a) # → [1, 2, 3] ← 変わらない!✅
print(b) # → [1, 2, 3, 4]
これでaとbは別々のリストオブジェクトになるので、片方を変えてももう片方には影響しません。
⚠️ ネストしたリストには注意!
ただし、リストの中にリストが入っている(ネスト構造)場合は、上記の方法では浅いコピー(shallow copy)しかされません。
完全に独立したコピーが必要なときは、copyモジュールのdeepcopy()を使いましょう。
import copy
a = [[1, 2], [3, 4]]
b = copy.deepcopy(a) # 深いコピー(deep copy)
b[0].append(99)
print(a) # → [[1, 2], [3, 4]] ← 変わらない!✅
print(b) # → [[1, 2, 99], [3, 4]]
まとめ
Pythonの変数は「データの入れ物」ではなく、オブジェクトへの参照(名前)です。リストを別の変数に代入するだけでは、同じリストを2つの名前で指しているにすぎません。本当にコピーしたいときは .copy() やスライス [:] を使うことを覚えておきましょう!
ぜひ自分のコードで実際に試してみてください 🐍✨ この仕組みを理解しておくと、将来的に関数へのリスト渡しでもハマらずに済みますよ。





