はじめに
pythonでリストを生成するときの書き方としては以下の2つがあると思います。
# []で生成
list_1 = []
# list()で生成
list_2 = list()
個人的には、前者の方がわかりやすいので[]
を使っていたのですが、
同じチーム内にlist()
で書く人もいて、コードレビューのときに「結局どっちがいいんだっけ?」の議論になったので両者の違いをまとめようと思います。
結論
以下の観点から[]
を使うルールにしました。
読みやすさ
-
[]
は他の多くのプログラミング言語(例えば JavaScript、C++、Java など)でも配列やリストを表すのに使われており、一般的に慣れ親しんだ表現であること。- Pythonの教育/学習資料でも、空のリストを生成する標準的な方法として
[]
が紹介されている印象。
- Pythonの教育/学習資料でも、空のリストを生成する標準的な方法として
- シンプルに
[]
の方が簡潔
一方で、list()
はpython特有の記法であり、pythonに精通していない人は一瞬「?」となる。
パフォーマンス
-
[]
はlist()
よりも生成が速い。
検証してみた
両方の書き方でそれぞれ空のリストを100万回作成する時間をtimeitを使って計測したところ、[]
のほうが速いことが確認できました。
In [1]: import timeit
...:
...: # `list()` を使って空のリストを生成する時間を計測
...: time_list = timeit.timeit('list()', number=1000000)
...:
...: # `[]` を使って空のリストを生成する時間を計測
...: time_brackets = timeit.timeit('[]', number=1000000)
...:
...: print(f"list()生成時間: {time_list} 秒")
...: print(f"[]生成時間: {time_brackets} 秒")
list() の生成時間: 約0.128秒
[] の生成時間: 約0.041秒
なお、1000万回の場合の結果は以下となり、大量にリストを生成するほど速度差が顕著に現れました。
list() の生成時間: 約1.291秒
[] の生成時間: 約0.486秒
なぜ速度に差が出るのか?
以下の記事が参考になりました。
https://towardsdatascience.com/no-and-list-are-different-in-python-8940530168b0
前提として、両者の違いは以下になります。
-
[]
はリテラル値である -
list()
は「リテラル値[]
を返す関数」である
上記の記事でも紹介されていますが、両者の処理をdis
モジュールを使ってバイトコードで確認すると一目瞭然でした。
In [1]: from dis import dis
# list()の処理
In [2]: dis("list()")
1 0 LOAD_NAME 0 (list)
2 CALL_FUNCTION 0
4 RETURN_VALUE
# []の処理
In [3]: dis("[]")
1 0 BUILD_LIST 0
2 RETURN_VALUE
上記のdis
モジュールによる解析から、list()
と[]
における速度差の主な理由は、実行されるオペレーションの違いにあることがわかりました。具体的には以下の点です。
-
リテラル
[]
-
[]
はリストを直接生成するリテラルであり、BUILD_LIST 命令を使用して空のリストを生成しているだけなので高速。
-
-
list()
-
list()
は関数であり、最終的には[]
でリストを生成する。まず最初に関数list
を LOAD_NAME 命令でロードし、その後 CALL_FUNCTION 命令で関数を呼び出している。この追加のステップによってオーバーヘッドが生じ、[]
と比較して処理が遅くなっている。
-
リストを作った後の操作も処理速度に違いってあるの?
リストを生成した後の操作(要素の追加や削除など)に関しては、リストがlist()
または[]
で生成されたかによる処理速度の違いはないです。
これは、どちらの方法でも生成されたオブジェクトは同じPythonのリスト型であるためです。パフォーマンスの違いはあくまでもリストの生成方法の違いに起因するものです。
さいごに
パフォーマンスの観点に関しては、大量のリストを頻繁に生成する必要がある場合に効いてくると思いますが、日常的なスクリプトや小中規模のアプリケーションの開発でこの差が顕著な違いを生むことは少ないのかなと思います。
なので、処理速度を気にしないのであれば、どっちを採用するのかはぶっちゃけ好みの問題なのかなと思っています。
私は今後も[]
で書きますが、もしかしたらパイソニックな書き方はlist()
のほうかもしれないですね…