Pythonにおけるリスト(list)と配列(array)の違い

はじめに

リスト(list)と配列(array)を厳密に使い分けていない情報が散見されます。本記事では、両者の違いをまとめようと思います。

listの基本

リスト(list)はシーケンス型(順番を保持した、要素の集まり)の一つです。

1
2
A = [2, 3, 4]
B = ['apple', 'orange']

arrayの基本

標準ライブラリarrayは、実はlistとほとんど同じです。大きな違いは、arrayでは格納するオブジェクトの型が全て同じである必要がある点です。この制約をメリットと感じられない場合はlistを使えば問題ないでしょう。実際、標準ライブラリのarrayはほとんど使われることはありません。

では、listだけ覚えればよいのでしょうか。 いえ、Pythonで配列としてよく利用されるクラスnumpy.ndarrayについても理解をしておくと良いでしょう。

numpy.ndarrayの基本

NumPyPythonの数値計算ライブラリで、標準ライブラリではないものの非常に多くのユーザに利用されています。そんなNumPyndarrayは次のように利用します。

1
2
import numpy as np
C = np.array([2,3,4])

listとnumpy.ndarrayの比較

実行速度

timeitを用いて速度を計測する
まずは、要素数が1000のlistndarrayを準備する。

1
2
ones = [1] * 1000
np_ones = np.array(ones)
  • sum ndarrayの方が高速

    1
    2
    3
    4
    >>> %timeit sum(ones)
    8.06 µs ± 274 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
    >>> %timeit np_ones.sum()
    2.58 µs ± 31 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
  • max ndarrayの方が高速

    1
    2
    3
    4
    >>> %timeit max(ones)
    16.3 µs ± 779 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
    >>> %timeit np_ones.max()
    3.11 µs ± 68.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
  • for文 listの方が高速

    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> %%timeit
    >>> for i in ones:
    >>> pass
    9.3 µs ± 680 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

    >>> %%timeit
    >>> for i in np_ones:
    >>> pass
    45.8 µs ± 2.83 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  • 演算 ndarrayの方が高速

まとめて演算した際の実行速度を考える。listでは以下のようにしても要素ごとの演算は行われずエラーとなる。

1
>>> ones / 2

そのため、リスト内包表記を用いる必要がある。

1
2
3
4
5
6
7
8
>>> %timeit [one+1 for one in ones]
46.7 µs ± 3.91 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>>> %timeit np_ones + 1
1.33 µs ± 61.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
>>> %timeit [a+b for a,b in zip(ones,ones)]
54.5 µs ± 3.89 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>>> %timeit np_ones + np_ones
1.11 µs ± 69.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

相互変換

1
2
ls = arr.tolist()
arr = np.array(ls)

まとめ

  • arrayを使うケースはあまりない
  • listnumpy.ndarrayを使い分ける
    • 数値計算を伴う場合はnumpy.ndarrayが適している場合が多く、そうでなければlistで十分

記事情報

  • 投稿日:2020年2月5日
  • 最終更新日:2020年5月3日