このページで解説している内容は、以下の YouTube 動画の解説で見ることができます。

【Python入門】リストを代入する時の注意点

リストを代入する時の注意点

 Pythonにおけるリストの代入は非常に便利ですが、その動作を正しく理解していないと予期せぬ結果を招くことがあります。特に、リストを別の変数に代入した際に、元のリストと新しい変数が同じリストオブジェクトを参照している場合、どちらか一方を変更するともう一方にも影響を与えることになります。
 ここでは、リストの代入時に注意すべき点や、リストのコピーを正しく作成する方法について詳しく解説します。これにより、リスト操作時の誤操作を防ぎ、プログラムの信頼性を高めることができます。

プログラムのダウンロード

 「ダウンロード」から、JupyterLab で実行できるサンプルプログラムがダウンロードできます。ファイルは、ESET Endpoint Securityでウイルスチェックをしておりますが、ダウンロードとプログラムの実行は自己責任でお願いいたします。

1.リストの代入に伴う参照の共有

 リストを別の変数に代入する際、単純な代入操作では新しい変数が元のリストを参照するようになります。これにより、どちらか一方のリストを変更すると、もう一方にもその変更が反映されます。

1.1. 参照の共有による影響

例えば、以下のようにリストを作成し、変数 original に代入します。

サンプルプログラム

# オリジナルのリストを作成
original = ['red', 'green', 'blue', 'yellow']
print(original)  # 出力: ['red', 'green', 'blue', 'yellow']

実行結果

['red', 'green', 'blue', 'yellow']

次に、変数 copy_reforiginal を代入します。

# リストを別の変数に代入
copy_ref = original
print(copy_ref)  # 出力: ['red', 'green', 'blue', 'yellow']

実行結果

['red', 'green', 'blue', 'yellow']

ここで、copy_ref を変更すると original も同様に変更されます。

# copy_ref の要素を変更
copy_ref[3] = 'purple'
print(copy_ref)   # 出力: ['red', 'green', 'blue', 'purple']
print(original)   # 出力: ['red', 'green', 'blue', 'purple']

実行結果

['red', 'green', 'blue', 'purple']
['red', 'green', 'blue', 'purple']

 このように、originalcopy_ref は同じリストオブジェクトを参照しているため、一方の変更が他方にも影響します。

1.2. 参照の共有を視覚化する

 以下の表は、変数 originalcopy_ref が同じリストオブジェクトを参照している状況を示しています。

メモリ上のオブジェクト参照先メモリ上の変数(一覧)
アドレス: 3000000型
リスト値: ['red', 'green', 'blue', 'purple']
変数名: original
参照先: アドレス 3000000
変数名: copy_ref
参照先: アドレス 3000000

id関数を使用して、originalcopy_ref が同じオブジェクトを指していることを確認できます。

サンプルプログラム

print(id(original))   # 例: 140352303995200
print(id(copy_ref))   # 例: 140352303995200

実行結果

1796291676224
1796291676224

両者の id が同じであることから、同一のオブジェクトを参照していることがわかります。

2.リストのコピーを作成する方法

 異なる変数が独立したリストオブジェクトを参照するようにするためには、リストのコピーを作成する必要があります。リストのコピーを作成する方法として、スライスを使用する方法と copy() メソッドを使用する方法の二つがあります。

2.1. スライスを使用したリストのコピー

スライスを使用すると、元のリストの全要素を新しいリストにコピーすることができます。

例:スライスを使ってリストをコピー

サンプルプログラム

# オリジナルのリストを作成
original = ['red', 'green', 'blue', 'yellow']
print(original)  # 出力: ['red', 'green', 'blue', 'yellow']

# スライスを使ってコピーを作成
copy_slice = original[:]
print(copy_slice)  # 出力: ['red', 'green', 'blue', 'yellow']

# copy_slice の要素を変更
copy_slice[3] = 'purple'
print(copy_slice)   # 出力: ['red', 'green', 'blue', 'purple']
print(original)     # 出力: ['red', 'green', 'blue', 'yellow']

実行結果

['red', 'green', 'blue', 'yellow']
['red', 'green', 'blue', 'yellow']
['red', 'green', 'blue', 'purple']
['red', 'green', 'blue', 'yellow']

 このように、スライスを使用して作成した copy_sliceoriginal とは別のリストオブジェクトとなり、独立して変更が可能です。

2.2. copy() メソッドを使用したリストのコピー

copy() メソッドを使用しても、リストの浅いコピーを作成することができます。

例:copy() メソッドを使ってリストをコピー

サンプルプログラム

# オリジナルのリストを作成
original = ['red', 'green', 'blue', 'yellow']
print(original)  # 出力: ['red', 'green', 'blue', 'yellow']

# copy() メソッドを使ってコピーを作成
copy_method = original.copy()
print(copy_method)  # 出力: ['red', 'green', 'blue', 'yellow']

# copy_method の要素を変更
copy_method[3] = 'purple'
print(copy_method)   # 出力: ['red', 'green', 'blue', 'purple']
print(original)      # 出力: ['red', 'green', 'blue', 'yellow']

実行結果

['red', 'green', 'blue', 'yellow']
['red', 'green', 'blue', 'yellow']
['red', 'green', 'blue', 'purple']
['red', 'green', 'blue', 'yellow']

 copy() メソッドを使用して作成した copy_method も、元のリスト original とは独立したリストオブジェクトとなり、個別に変更が可能です。

まとめ

以下の表に、ここで解説した「リストを代入する時の注意点」に関する主要なポイントをまとめます。

項目説明
リストの代入による参照の共有リストを単純に代入すると、元のリストと新しい変数が同じリストオブジェクトを参照する。
参照の共有による影響一方のリストを変更すると、もう一方のリストにも変更が反映される。
スライスによるリストのコピースライス [:] を使用してリストの浅いコピーを作成し、独立したリストを作成する。
copy() メソッドによるリストのコピーcopy() メソッドを使用してリストの浅いコピーを作成し、独立したリストを作成する。
参照とコピーの違い参照は同一オブジェクトを指すのに対し、コピーは独立した新しいオブジェクトを指す。
id() 関数の活用id() 関数を使用して、変数が同じオブジェクトを参照しているかどうかを確認する。

 次のコンテンツでは、リスト要素の追加と削除について詳しく解説していきます。リストに新しい要素を追加したり、不要な要素を削除する方法を学び、リスト操作の幅を広げましょう。

 Pythonのリスト操作は多岐にわたります。ここで学んだリストの代入時の注意点を理解し、次章ではリストの要素追加・削除の方法をマスターしましょう。