Python学習チャンネル by PyQ

Pythonのオンライン学習プラットフォームPyQのオフィシャルブログです

Pythonでリストのスライスに`.append`しても変更されない?への回答

f:id:kenken0326:20200625165922p:plain

こんにちは、id:hirokikyです。 今日は、「Pythonでリストのスライスに .append してもリストが変更されないぞ?」という問題の解決法を説明します。

直接この記事がお役に立てるかはわかりませんが、Pythonにおけるリストやスライス、 .append について知ることで解決の一助になれると嬉しいです。

いただいたご質問

リストのある位置に値を追加しようと以下のように書きましたが、何の変化もありませんでした。
リスト.append として要素を追加しようとしましたが、なぜ何も追加されないのでしょうか?
どうすれば良いのかと、なぜこうなっているのかを教えてください。

snakes = ["corn", "ball", "green", "boa"]

# リストの中に値を追加したい
snakes[1:3].append("milk")

print(snakes)  # 結果は ['corn', 'ball', 'green', 'boa'] になる

Pythonでリストのスライスに.appendしても変更されない?への回答

snakes[1:3].append しても内容が変わらないということですね。
もし「リストのn番目に要素を追加したい」ということであれば、以下のように リスト.insert(Index番号, 追加したい要素) を使ってください。

snakes = ["corn", "ball", "green", "boa"]
snakes.insert(1, "milk")

print(snakes)  # ['corn', 'milk', 'ball', 'green', 'boa']

.append を使うのはリストの末尾に値を追加するときに使いましょう。

.append(...)しているのに追加されなかった意味の解説

質問のPythonプログラムで.appendとしたのに値が追加されなかった理由を解説します。

snakes[1:3] を実行すると、Pythonは snakes の2,3番目の要素を取り出したリストをコピーします(正確には浅いコピーをします)。snakes[1:3] はコピーされた ["ball", "green"] というリストになります。

snakes[1:3].append(...) とすると、このコピーされたリストに .append(...) を実行するので、結果は ["ball", "green", "milk"] となります。
しかし、この実行された結果はどこにも代入されていない値になります。どこにも代入されていない値は、見つけようもないので消えてしまいます。

なぜ リスト[:].append(...) ではダメなのか

snakes[1:3].append("milk") で実行される処理を箇条書きにすると以下のようになります。

  1. snakesから2、3番目を取り出したリストがコピーされる
  2. コピーされたリスト `["ball", "green"]` に "milk" が追加される
  3. このコピーされたリストは代入されていないので消える

以下のように書き換えれば、.appendした結果が消えません(もともと期待している動作とは違いますが)。

1行目でスライスした結果を代入しなおしていることに注意してください。

snakes = snakes[1:3]
snakes.append("milk")
print(snakes)  # ['ball', 'green', 'milk'] になります

ただし、以下はうまくいきません。
.append(...) の実行結果である None が代入されるだけになります。実行すると snakesNone になり、元のリストは消えてしまいます。

snakes = [...]
snakes = snakes[1:3].append("milk")

print(snakes)  # リストがNoneになってしまった!

リストのスライスとappendのまとめ

ポイントは以下の3つです。

  • スライスは元のリストのコピーを作成します
  • .append(...) はリストの内容を変更しますが、値は返しません(Noneを返します)
  • 代入されない値は消えてしまいます

「Pythonでリストのスライスに.appendしても変更されない?」という疑問はすごく良い疑問ですが、理解するのは少しむずかしいかもしれません。
難しいときは「なるほど、こういうこともあるのか」とやんわり理解されるだけでもOKです。

リストの中に値を追加するときは、 .append() ではなく .insert() を使うと覚えておけば問題ありません。

Copyright ©2017-2020 BeProud Inc. All rights reserved.