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のような名前を推奨
このエントリーをはてなブックマークに追加
にほんブログ村 IT技術ブログへ

コメント

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です