Pythonリストの中身を丸ごと置き換える方法【スライス代入】
Pythonにおいて、list[:] = new_listという構文は、リストの内容を新しいリストで置き換えるための便利な手法です。この方法を使うと、元のリストの参照を保持したまま、その内容を更新することができます。以下に、この構文の動作や利点について詳しく解説します。
こんな場面で役立ちます
- 関数の引数で受け取ったリストの更新を、呼び出し元にも反映する場面
- 同じリストを複数の変数や複数のクラスで共有している場面
- リストの参照は変えず、中身だけを総入れ替えする場面
動作の仕組み
スライス構文とは
my_list[:]は、リストの先頭から末尾までの範囲(スライス)を表します。スライスを使うと、リストの全体や一部を取り出したり、書き換えたりできます。
式の右側と左側で意味が変わる
[:]は、書く位置によって別の動きをします。
- 右側に書く(
copied = my_list[:]): 新しいリスト(浅いコピー)の作成 - 左側に書く(
my_list[:] = new_list): そのリストの中身のまるごと置き換え
右側に書いた場合は、次のように元のリストとは別のオブジェクトになります。
my_list = [1, 2, 3]
copied = my_list[:]
print(copied == my_list) # True(中身は同じ)
print(copied is my_list) # False(別のリスト)
浅いコピーなので、リストの中にリストが入っている場合、内側のリストまではコピーされず共有されます。
左側に書いた場合は、新しいリストは作られません。元のリストの要素がnew_listの要素に入れ替わります。置き換え後のリストはnew_listと同じ長さになり、元の長さは関係ありません。
例
以下に、具体的な例を示します。
# 元のリスト
original_list = [1, 2, 3, 4, 5]
print("Before:", original_list)
# 新しいリスト
new_list = [10, 20, 30]
# スライスを使って内容を更新
original_list[:] = new_list
print("After:", original_list)
出力は次のようになります。
Before: [1, 2, 3, 4, 5]
After: [10, 20, 30]
my_list = new_listとの違い
単にmy_list = new_listと書くと、変数my_listの指す先が変わるだけです。同じリストを指していた別の変数は、古いリストを見たままになります。
my_list = [1, 2, 3]
alias = my_list # 同じリストを指す別名
new_list = [10, 20, 30]
my_list = new_list # 指す先を付け替えただけ
print(my_list) # [10, 20, 30]
print(alias) # [1, 2, 3] ← 古いまま
冒頭の「別の変数が古いまま」という現象は、この付け替えが原因です。スライス代入に変えると解消します。
特徴と利点
同じリストを見ている他の変数にも反映される
スライス代入では、リストそのもの(参照先)は変わらず、中身だけが入れ替わります。id()で調べると、置き換えの前後で同じリストであることが確認できます。
my_list = [1, 2, 3]
alias = my_list
old_id = id(my_list)
my_list[:] = [10, 20, 30]
print(id(my_list) == old_id) # True(同じリストのまま)
print(my_list) # [10, 20, 30]
print(alias) # [10, 20, 30] ← 別名側にも反映
中身の書き換えだと分かる
my_list[:] = ...と書くと、変数の付け替えではなく、リストの内容を変更していることがコードから読み取れます。
注意点
長さは新しいリストに合わせて変わる
置き換え後のリストは、新しいリストと同じ長さになります。元より長くなることも、短くなることもあります。
my_list = [1, 2, 3]
my_list[:] = [7, 8, 9, 10, 11]
print(my_list) # [7, 8, 9, 10, 11]
右側はリスト以外でも使える
右側には、タプルなど、要素を順番に取り出せるもの(イテラブル)を指定できます。
my_list = [1, 2, 3]
my_list[:] = (5, 6)
print(my_list) # [5, 6]
文字列もイテラブルなので、my_list[:] = "abc"とすると['a', 'b', 'c']のように1文字ずつに分かれます。意図しない場合は、渡す値の型を確認してください。
変数名にlistを使わない
listは Python の標準関数(組み込み関数)と同じ名前です。変数名に使うと標準のlist()が使えなくなるため、この記事ではmy_listのような名前にしています。
反映は意図どおりか確認する
同じリストを見ているすべての変数が変更後の内容になります。共有したい場合は利点ですが、他の処理が元の内容を前提にしていると、意図しない副作用になります。
まとめ
my_list[:] = new_listは、リストを保ったまま中身だけを置き換える書き方- 同じリストを見ている他の変数にも変更が反映される点
my_list = new_listは付け替えのため、他の変数は古い内容のまま- 置き換え後の長さは新しいリストと同じで、右側はタプルなどのイテラブルも指定可能
- 変数名は
listではなくmy_listのような名前を推奨
