Pythonでリストや辞書などのオブジェクトを扱う際、変数が予期せず上書きされる現象が発生することがあります。この記事では、その原因と対処法について解説します。
原因: 参照渡し
Pythonでは、リストや辞書などのオブジェクトは参照渡しで扱われます。これは、オブジェクトの実体ではなく、オブジェクトへの参照(アドレス)が渡されることを意味します。そのため、関数にリストを渡したり、リストを別のリストに代入すると、元のリストと新しいリストが同じオブジェクトを参照することになります。
def add_element(list1, element):
list1.append(element)
list_a = [1, 2, 3]
list_b = list_a
add_element(list_a, 4)
print(list_a) # [1, 2, 3, 4]
print(list_b) # [1, 2, 3, 4]
上記の例では、list_a
とlist_b
は同じオブジェクトを参照しているため、list_a
に要素を追加すると、list_b
の内容も変更されます。
対処法
値渡しを利用する
値渡しは、変数の値を直接渡す方法です。これにより、参照先のオブジェクトが変更されても、元の変数の値は影響を受けません。
original_list = [1, 2, 3]
new_list = []
for item in original_list:
new_list.append(item)
new_list[0] = 99
print(original_list) # [1, 2, 3]
print(new_list) # [99, 2, 3]
リスト内包表記を使う
リスト内包表記を使うことで、ループ内でのappend
関数の使用を避けることができます。
original_list = [1, 2, 3]
new_list = [item for item in original_list]
new_list[0] = 99
print(original_list) # [1, 2, 3]
print(new_list) # [99, 2, 3]
deepcopy
を利用する
deepcopy
は、Pythonのcopy
モジュールにある関数で、オブジェクトの完全なコピーを作成します。これにより、ネストされたリストや辞書などの複雑なデータ構造も正確にコピーすることができます。
from copy import deepcopy
original_list = [[1, 2], [3, 4]]
new_list = deepcopy(original_list)
new_list[0][0] = 99
print(original_list) # [[1, 2], [3, 4]]
print(new_list) # [[99, 2], [3, 4]]
以上、Pythonで変数が上書きされる現象とその対処法について解説しました。これらの対処法を活用して、Pythonプログラミングをより効率的に行いましょう。