
PyQチームのtsutomuです。
今日は、Pythonにおけるスライスへの代入について紹介します。
スライスへの代入についてはPyQのクエスト「リストを使おう」の4問目でも扱っています。
このブログは、このクエストの補足になります。
スライスを使った代入
リストが入った変数lstを考えましょう。
lst = [1, 2, 3, 4]
このとき、スライスlst[1:4]は[2, 3, 4]になります。
要素数は、3個です。
スライスに、スライスと同じ要素数を代入する場合
リストの場合、次のようにスライスを使って代入できます。
lst[1:4] = [20, 30, 40]
上記を実行すると、lst[1:4]は[20, 30, 40]になります。lstは、[1, 20, 30, 40]です。
また、右辺(=の右側)はイテラブルであれば良いので、下記のように右辺の角括弧は丸括弧にできます。
(20, 30, 40)はタプルです。
lst[1:4] = (20, 30, 40)
タプルは丸括弧を省略できるので、下記のようにも書けます。
lst[1:4] = 20, 30, 40
スライスに、スライスと異なる要素数を代入する場合
ここからは、左辺と右辺で要素数の異なるものを代入してみましょう。
lst[1:4] = 20, 30
上記を実行すると、要素数が3個あった場所に2個の要素を代入します。
その結果、lstの要素数は1つ減って3個になります。
すなわち、lstは[1, 20, 30]になります。
このように、リストのスライスには要素数が異なるものを代入できます。
そのときリストそのものの要素数が変化します。
リスト全体にスライスを使って代入する場合
スライスでlst[:]のようにインデックスを省略すると、全体になります。
ここで、下記のコードを考えてみます。このコードを実行するとlstは空になります。
lst[:] = []
もう少し詳しく言うと、lstの全要素を空のリストで置き換えます。
この結果すべての要素が削除されます。
この処理は、下記とは異なります。
lst = []
上記を実行すると、もともとのlstの要素は変更されずに、「新しい空のリスト」が作られてlstという名前をつけます。
次のようにすると違いを確認できます。
lst = [1, 2, 3, 4] lst2 = lst # lstとlst2は同じリスト lst2 = [] # 別の空のリストを代入するだけで、lstはそのまま print(lst) # [1, 2, 3, 4] と出力 lst2 = lst # lstとlst2は同じリスト lst2[:] = [] # リストの中身を空にするので、lstも空に print(lst) # [] と出力
最初に、lstには[1, 2, 3, 4]が入っています。
ここで、一旦lst2 = lstとします。このとき、lstとlst2は同じリストを指しています。
次に、lst2 = []とすると、lst2がlstとは別の空のリストを指すように変わります。
このとき、lstの中身は変わりません。これは、print(lst)の出力が[1, 2, 3, 4]となることで確認できます。
もう一度、lst2 = lstとし、lst2がlstと同じリストを指すようにします。
そこで、lst2[:] = []を実行すると、リストの中身を空にします。このリストはlstが指しているものと同じです。
そのため、print(lst)の出力は[]となり、lstも空になっていることが確認できます。
このように、リストのスライスに代入することは、リストの中身を変更することです。
lst[:] = []という書き方を見かけても、驚かないようにしましょう。
まとめ
スライスへの代入について、同じ要素数を代入する場合・異なる要素数を代入する場合・リスト全体にスライスを用いて代入する場合に分けて紹介しました。