1次元配列を作成する場合は、それをリストとして実装するか、標準ライブラリの「配列」モジュールを使用できます。私は常に1次元配列のリストを使用しています。
代わりにアレイモジュールを使用する理由または状況は何ですか?
パフォーマンスとメモリの最適化のためですか、それとも明らかなものがないですか?
1次元配列を作成する場合は、それをリストとして実装するか、標準ライブラリの「配列」モジュールを使用できます。私は常に1次元配列のリストを使用しています。
代わりにアレイモジュールを使用する理由または状況は何ですか?
パフォーマンスとメモリの最適化のためですか、それとも明らかなものがないですか?
回答:
基本的に、Pythonリストは非常に柔軟であり、完全に異種の任意のデータを保持でき、償却済みの一定時間内に非常に効率的に追加できます。リストを時間効率よく、面倒なく縮小および拡大する必要がある場合は、それらを使用する方法です。ただし、C配列よりもはるかに多くのスペースを使用します。
array.array
型が、一方、Cアレイ上だけ薄いラッパーです。同じタイプの同種のデータのみを保持できるためsizeof(one object) * length
、メモリのバイトのみを使用します。ほとんどの場合、C配列を拡張機能またはシステムコール(ioctl
またはfctnl
)に公開する必要がある場合に使用します。
array.array
また、Python 2.x()で可変文字列を表すための妥当な方法array('B', bytes)
です。ただし、Python 2.6+および3.xでは、可変バイト文字列がとして提供されbytearray
ます。
ただし、数値データの同種配列で数学を実行する場合は、複雑な多次元配列での演算を自動的にベクトル化できるNumPyを使用する方がはるかに便利です。
長い話を短くするようにするには:array.array
あなたは理由のためのデータの均質なC配列必要がある場合に有用である数学をやっ以外を。
sizeof(element)
×(要素の数)バイトと、オーバーヘッド用の小さな固定ヘッダーを必要とします。しかし、ndarray大きな配列にメモリを割り当てるためのいくつかのプラグイン可能な戦略を不連続とスパース配列を扱うためのいくつかの高度なオプションを持っている、と私は思う...これらの高度な機能のいくつかは、それをユーザーになります少ない他の人が使用してパフォーマンスを向上させる一方で、メモリをよりメモリ。
ほとんどの場合、通常のリストが適切な選択です。配列モジュールは、C配列のシンラッパーのようなもので、厳密に型指定されたコンテナー(docsを参照)の一種を提供し、ビルドの一部ではない、signed / unsigned shortやdoubleなどのCのような型にアクセスできます。タイプ。本当に必要な場合にのみ配列モジュールを使用します。それ以外の場合はすべてリストを使用します。
array
は数学を行うためのものではありません。ndarray
10 ^ 8の数値の配列を合計するためにNumPyを試してみると、完全に吹き飛ばされlist
てしまいます。@tzotは、組み込みのarray
計算が遅い理由について正しい考えを持っています。
アレイモジュールは、なぜそれを使用するのかわからない場合におそらく必要のないものの1つです(そして、私はそれを降順で言っているわけではないことに注意してください!) 。ほとんどの場合、配列モジュールはCコードとのインターフェースに使用されます。パフォーマンスに関する質問へのより直接的な回答を提供するには:
一部の用途では、配列はリストよりも効率的です。変更されないことがわかっている配列を割り当てる必要がある場合は、配列を高速化し、使用するメモリを少なくすることができます。GvRには、アレイモジュールが勝者となる最適化の逸話があります(長い記事ですが、それだけの価値があります)。
一方、リストが配列よりも多くのメモリを消費する理由の一部は、割り当てられたすべての要素が使用されると、Pythonがいくつかの追加の要素を割り当てるためです。つまり、アイテムをリストに追加する方が高速です。したがって、アイテムの追加を計画している場合は、リストが適しています。
TL; DR例外的な最適化が必要な場合、またはCコードとのインターフェースが必要な場合(およびpyrexを使用できない場合)は、配列のみを使用します。
それはトレードオフです!
それぞれの長所:
配列を使用する場合は、numpyまたはscipyパッケージを検討してください。これにより、配列の柔軟性が大幅に向上します。
配列は特定のタイプにのみ使用できますが、リストは任意のオブジェクトに使用できます。
配列は1つのタイプのデータのみを含むこともできますが、リストにはさまざまなオブジェクトタイプのエントリを含めることができます。
配列は数値計算にとってもより効率的です。
この答えは、ListとArrayをいつ使用するかに関するほぼすべてのクエリを要約したものです。
これら2つのデータ型の主な違いは、それらに対して実行できる操作です。たとえば、配列を3で除算すると、配列の各要素が3で除算されます。リストでは同じことはできません。
リストはpythonの構文の一部なので、宣言する必要はありませんが、使用する前に配列を宣言する必要があります。
異なるデータ型の値をリスト(異種)に格納できますが、配列では同じデータ型(同種)の値のみを格納できます。
配列は機能が豊富で高速なので、リストと比較して、算術演算や大量のデータの格納に広く使用されています。
配列は、リストと比較して必要なメモリが少なくなります。
パフォーマンスに関して、Pythonリスト、配列、およびnumpy配列を比較するいくつかの数値を示します(すべて2017 Macbook ProのPython 3.7で)。最終結果は、これらの操作に対してPythonリストが最速になることです。
# Python list with append()
np.mean(timeit.repeat(setup="a = []", stmt="a.append(1.0)", number=1000, repeat=5000)) * 1000
# 0.054 +/- 0.025 msec
# Python array with append()
np.mean(timeit.repeat(setup="import array; a = array.array('f')", stmt="a.append(1.0)", number=1000, repeat=5000)) * 1000
# 0.104 +/- 0.025 msec
# Numpy array with append()
np.mean(timeit.repeat(setup="import numpy as np; a = np.array([])", stmt="np.append(a, [1.0])", number=1000, repeat=5000)) * 1000
# 5.183 +/- 0.950 msec
# Python list using +=
np.mean(timeit.repeat(setup="a = []", stmt="a += [1.0]", number=1000, repeat=5000)) * 1000
# 0.062 +/- 0.021 msec
# Python array using +=
np.mean(timeit.repeat(setup="import array; a = array.array('f')", stmt="a += array.array('f', [1.0]) ", number=1000, repeat=5000)) * 1000
# 0.289 +/- 0.043 msec
# Python list using extend()
np.mean(timeit.repeat(setup="a = []", stmt="a.extend([1.0])", number=1000, repeat=5000)) * 1000
# 0.083 +/- 0.020 msec
# Python array using extend()
np.mean(timeit.repeat(setup="import array; a = array.array('f')", stmt="a.extend([1.0]) ", number=1000, repeat=5000)) * 1000
# 0.169 +/- 0.034