Python - リストのコピー

こんにちは、Pythonプログラマー志願者の皆さん!今日は、Pythonでリストをコピーする魅力的な世界に飛び込んでいきましょう。あなたの親しみのある近所のコンピュータサイエンスの先生として、私は明確な説明、たくさんの例、そして途中で冗談も一つか二つを交えて、この旅を案内してあげます。では、始めましょう!

Python - Copy Lists

Pythonでリストをコピーする

異なる方法でリストをコピーする前に、まずなぜリストをコピーする必要があるのかを理解しましょう。ショッピングリストをお持ちして、それをルームメイトと共有したいと思ったとしましょう。彼に元のリストを渡すことはできますが、彼が「チョコレート」を追加することにするとどうなるでしょうか(誰がやらないでしょう)?突然、慎重に計画された健康的なショッピングリストが危険にさらされてしまいます!これがコピーが役立つ場面です。

Pythonでは、リストを新しい変数に割り当てると、新しいリストを作成しているわけではありません。代わりに、同じリストに対する新しい参照を作成しています。これを実際に見てみましょう:

original_list = [1, 2, 3, 4, 5]
new_list = original_list

print("Original list:", original_list)
print("New list:", new_list)

new_list.append(6)

print("Original list after modification:", original_list)
print("New list after modification:", new_list)

出力:

Original list: [1, 2, 3, 4, 5]
New list: [1, 2, 3, 4, 5]
Original list after modification: [1, 2, 3, 4, 5, 6]
New list after modification: [1, 2, 3, 4, 5, 6]

驚きましたか?どちらのリストも変更されたのは、実際には同じメモリ内のリストだからです。これが、コピーが救助に来る場面です!

Pythonリストの浅いコピー

浅いコピーは新しいリストオブジェクトを作成しますが、新しいリストの要素は元のリストの同じオブジェクトへの参照です。これは、ショッピングリストのフォトコピーを作るようなものです - 新しい紙を持っていますが、その上に書かれているアイテムは同じです。

浅いコピーを作成する方法を見てみましょう:

import copy

original_list = [1, [2, 3], 4]
shallow_copy = copy.copy(original_list)

print("Original list:", original_list)
print("Shallow copy:", shallow_copy)

shallow_copy[1][0] = 'two'

print("Original list after modification:", original_list)
print("Shallow copy after modification:", shallow_copy)

出力:

Original list: [1, [2, 3], 4]
Shallow copy: [1, [2, 3], 4]
Original list after modification: [1, ['two', 3], 4]
Shallow copy after modification: [1, ['two', 3], 4]

浅いコピーの中に入れたリストを変更すると、元のリストも変更されることに注意してください。なぜなら、入れ子になったリストはまだ同じメモリ内のオブジェクトへの参照だからです。

Pythonリストの深いコピー

一方、深いコピーは新しいリストを作成し、入れ子になったオブジェクトのコピーを再帰的に追加します。これは、ショッピングリストを手で全く新しく書くようなものです - すべてが新しいし、独立しています。

深いコピーを作成する方法を見てみましょう:

import copy

original_list = [1, [2, 3], 4]
deep_copy = copy.deepcopy(original_list)

print("Original list:", original_list)
print("Deep copy:", deep_copy)

deep_copy[1][0] = 'two'

print("Original list after modification:", original_list)
print("Deep copy after modification:", deep_copy)

出力:

Original list: [1, [2, 3], 4]
Deep copy: [1, [2, 3], 4]
Original list after modification: [1, [2, 3], 4]
Deep copy after modification: [1, ['two', 3], 4]

今回は、深いコピーを変更しても元のリストに影響を与えません。完全に独立しています!

スライス表記を使用してリストをコピーする

次に、リストをコピーする他の方法を見ていきましょう。最も簡単な方法の一つは、スライス表記を使用することです。これは、「リスト全体のコピーを始めから終わりまでほしい」と言うようなものです。

original_list = [1, 2, 3, 4, 5]
slice_copy = original_list[:]

print("Original list:", original_list)
print("Slice copy:", slice_copy)

slice_copy.append(6)

print("Original list after modification:", original_list)
print("Slice copy after modification:", slice_copy)

出力:

Original list: [1, 2, 3, 4, 5]
Slice copy: [1, 2, 3, 4, 5]
Original list after modification: [1, 2, 3, 4, 5]
Slice copy after modification: [1, 2, 3, 4, 5, 6]

この方法は、リストの浅いコピーを作成します。これは通常、数や文字列のような変更不可なオブジェクトのリストには十分です。

list()関数を使用してリストをコピーする

リストをコピーする別の方法は、list()関数を使用することです。これは、Pythonに「このような新しいリストを作ってください」と言うようなものです。

original_list = [1, 2, 3, 4, 5]
list_copy = list(original_list)

print("Original list:", original_list)
print("List copy:", list_copy)

list_copy.append(6)

print("Original list after modification:", original_list)
print("List copy after modification:", list_copy)

出力:

Original list: [1, 2, 3, 4, 5]
List copy: [1, 2, 3, 4, 5]
Original list after modification: [1, 2, 3, 4, 5]
List copy after modification: [1, 2, 3, 4, 5, 6]

この方法も、リストの浅いコピーを作成します。

copy()メソッドを使用してリストをコピーする

最後に、copy()メソッドを紹介します。これはリストのビルトインメソッドです。これは、リストが「ここ、自分のコピーを取ってください!」と言うようなものです。

original_list = [1, 2, 3, 4, 5]
copy_method = original_list.copy()

print("Original list:", original_list)
print("Copy method:", copy_method)

copy_method.append(6)

print("Original list after modification:", original_list)
print("Copy method after modification:", copy_method)

出力:

Original list: [1, 2, 3, 4, 5]
Copy method: [1, 2, 3, 4, 5]
Original list after modification: [1, 2, 3, 4, 5]
Copy method after modification: [1, 2, 3, 4, 5, 6]

この方法も、リストの浅いコピーを作成します。

次に、これらの方法を便利な表にまとめてみましょう:

方法 構文 コピーの種類 備考
代入 new_list = original_list 参照 本当のコピーではない
浅いコピー copy.copy(original_list) 浅い 新しいリスト、同じオブジェクト参照
深いコピー copy.deepcopy(original_list) 深い 新しいリスト、新しいオブジェクト参照
スライス表記 original_list[:] 浅い 簡単で読みやすい
list()関数 list(original_list) 浅い 意図が明確
copy()メソッド original_list.copy() 浅い リストのビルトインメソッド

覚えておくべきことは、正しいコピーメソッドを選ぶには、具体的なニーズに依存していることです。変更不可なオブジェクトのシンプルなリストに対しては、浅いコピーが通常十分です。しかし、入れ子になったリストや変更可能なオブジェクトがある場合、完全に独立させるために深いコピーが必要な場合があります。

それでは、これでリストをプロのようにコピーする知識をお持ちできました。次回、ショッピングリストを共有する際に、予期せぬ追加を冒すことなく、ちょうどいいコピーを作る方法を知っています。幸せなコーディングをお楽しみください、そして、あなたのリストが常に完璧にコピーされることを願っています!

Credits: Image by storyset