2通りあるPythonのリスト結合処理の違いを理解する
Python のリスト結合
Pythonに限った話ではないですが、リストとリストを結合する、というのはよくある処理だと思います。そういったよくある処理に限って、やり方が複数あって使い分けが重要になることもあったりするものです。
というわけで、今回は Pythonのリスト結合処理の書き方による違い についてまとめます。
ちなみに今回の内容は Pull-Request のレビューなどでも指摘する(あるいは最近だとAIが指摘してくれる)ことが多い内容です。
Pythonにおけるリスト結合の方法
そもそもの話として、Pythonでリストを結合する方法は主に2つあります。
+ 演算子を使った結合
一つ目は +
演算子を使うパターンです。
animals = ["panda", "rabbit"] new_animals = ["koala"] result = animals + new_animals print(result) # ["panda", "rabbit", "koala"]
こういうことですね。
リストとリストを足し算するような表記で結合できます。 出来上がったリストは新しいオブジェクトとなっているので、このようにオブジェクトへの代入(もしくは自らへの再代入)を行う必要があります。
extend メソッドを使った結合
animals = ["panda", "rabbit"] new_animals = ["koala"] animals.extend(new_animals) print(animals) # ["panda", "rabbit", "koala"]
こういうことです。
先ほどの +
演算子が新しいオブジェクトを作っていたのに対し、
こちらは、 animals
というリストオブジェクトをベースに拡張していく書き方となります。
これらのメソッドの違いについて考える
それでは本題のこれらの書き方による違いです。
メモリ効率とパフォーマンス
先ほども記述した通り、+
演算子は新しいオブジェクトを作っています。
それに対して extend
は既存のリストを拡張していくことになりますので、端的に言うと メモリ効率が良いということになります。
なので、規模の大きなリストになればなるほど、 extend
のほうが効果が大きくなるということになります。
どう使い分けるか
以上を踏まえると基本的にはリスト同士の結合であれば extend
を使えばいいやん、という話になりそうですが、
では、 +
演算子による処理は使うなという話になるのか?というとそんなことはありません。
たとえば、なんらかのベースになるリストを複数拡張するときには、ベースになるリスト自体に変更を加えたくないことがあります。
base_member = ["people"] def create_group(animal: list[str]) -> list[str]: """人間と動物のグループを意味するリストを作成する""" return base_member + animal # 常に people は含まれるグループを作る group1 = create_group(["panda", "rabbit"]) # ["people", "panda", "rabbit"] group2 = create_group(["koala"]) # ["people", "koala"]
みたいなことですね。
ここでもし
def create_group(animal: list[str]) -> list[str]: base_member.extend(animal) return base_member
としてしまうと、
group1 = create_group(["panda", "rabbit"]) # ["people", "panda", "rabbit"] group2 = create_group(["koala"]) # ["people", "panda", "rabbit", "koala"]
と、どんどん継ぎ足されていく挙動になってしまいます。
これくらいはまだ気付けるかもしれないのですが、
さらにいうと、 group1
も group2
も同じオブジェクトを指すので、同じ値が print されます。
print(group1) # ["people", "panda", "rabbit", "koala"] print(group2) # ["people", "panda", "rabbit", "koala"]
このように、迂闊に全部を extend
にしてしまうと思わぬ挙動に繋がることもあります。
というわけで、重要なのは、 extend
と +
で内部的にどのような変更が行われているかのイメージを掴んでおくことと言えるでしょう。
まとめ
今回は Python のリスト結合の方法による違いについてまとめました。
レビューをしていると、同じリスト操作系のメソッドでも、単一の値を加える append
はよくみますが、 extend
は特に +
で済ませてしまえることもあり、(使い分けを意識せずに)使えていないことも多い印象です。
ただ、こういった基本的な内容こそ品質に影響を与えたりすることもあるように思いますので、
append
extend
insert
のリスト操作系三兄弟についてはうまいこと使える場面では使っていきたいところですね。