2009-10-16 17 views
6

約200,000,000の真偽値のコレクションであるオブジェクトを、Pythonで作成したいと考えています。特定の真偽値を最も効果的に変更または再呼び出しできるように、123,456,000などの任意の数値がtrueまたはfalseかどうかを迅速に判断したり、値を変更したりすることができます。Pythonの非常に大きなブールリスト

このリストを作成する最善の方法はありますか?または配列?クラス?またはちょうどビットの操作を使用して長いint?または、他の何か?

私は少し戸惑いがありますので、私がよく知っている他の言語の1つで質問していた場合よりも、私のことを覚えておく必要があります。このオブジェクトの操作がどのように見えるかの例を教えてください。

おかげ

+3

真偽値は密であるか疎ですか?それらは均等に分布していますか、あるいは密度が高く、より狭い範囲になる可能性がありますか?データ構造の理想的な選択は、これらによって異なります。もちろん、あなたは「理想」を必要としないかもしれません。 – Steve314

答えて

12

bitarrayモジュールを試してみるか、arrayの整数を使って同様のことを書くことができます。

+0

ありがとう!私は前にモジュールをインストールしておらず、少し問題がある:http://superuser.com/questions/56316/python-module-trouble-installing-bitarray – Dan

3

あなたはSQLiteのような軽量のデータベースを使用して検討していますか?

+4

+1。2億ビットは約24メガバイトのデータですが、これは現代のマシンのメモリに簡単に収まるかもしれませんが、いつでもメモリ内のそのサイズの構造になると、データベースがより良いソリューションになるかどうかを少なくとも検討する必要があります。 –

4

"真の"セットまたは "偽の"セットで123,456,000のような任意の数字があるかどうかを迅速に判断します。

setが対象です。

「真」のセットは、すべての数字のセットです。

数値のブール値フラグを "true"にするには、それを真のセットに追加します。

数字のブールフラグを "false"にするには、真のセットから削除します。

人生ははるかに簡単です。

+1

+1:これは使いやすく、十分かもしれないスパースリストに対して効率的 – jfs

+0

値の半分が真であるとしましょう。 intオブジェクトのサイズは、実際のハッシュテーブルのキー+追加メモリを格納するためだけに1.2GBです。ビットアレイを使用すると、メモリ使用量は25MBになります。私はそれが大きな違いだと思う。 –

+0

@LukášLalinský:あなたの分析は良いです。しかし、あなたのプロセッサに使用可能なメモリがないかぎり、それは意味がないと思います。ほとんどの最新のプロセッサでは、十分なメモリがあり、25M vs. 1.2Gはまったく重要ではありません。 –

1

一見すると、PythonのBitVectorモジュールは、あなたが望むものとまったく同じように聞こえる。それはhttp://cobweb.ecn.purdue.edu/~kak/dist/BitVector-1.5.1.htmlで利用可能で、純粋なPythonコードなので、コンパイル不要の任意のプラットフォーム上で動作します。

あなたは、任意の真偽値を取得して設定する際にある程度スピードが必要であると述べました。そのためには、リストではなくPython配列を使用する必要があります。上記のURLに行き、BitVectorのソースコードを参照すると、実際にPython配列に依存していることがわかります。

理想的には、あなたは、このような特定の名前などに関連する情報を格納するためのリストを追加のようなものを行うことができますすなわち

class TFValues(BitVector): 
    pass 

こうすることで、あなたはビットベクトルからサブクラス化クラスで何をしているかをカプセル化しますTF値。

3

純粋なPythonであるbitstringモジュールを試してみることもできます。内部的には、すべてのバイト配列とビットマスクとして保存されているとシフトはあなたのために行われます。

from bitstring import BitArray 
# Initialise with two hundred million zero bits 
s = BitArray(200000000) 
# Set a few bits to 1 
s.set(1, [76, 33, 123456000]) 
# And test them 
if s.all([33, 76, 123456000]): 
    pass 

他のポスターは簡単なセットはあなたの特定の問題へのよりよい解決策になるかもしれないけれども正しいです。

関連する問題