54

ブール値の配列のコンパクトな表現が必要です。Python には組み込みのビットフィールド型がありますか、それとも別の解決策を見つける必要がありますか?

4

12 に答える 12

40

主に、ビット フィールドに名前を付けて簡単に操作できるようにしたい場合 (たとえば、通信プロトコルで単一ビットとして表されるフラグを操作する場合)、How Do Iで説明されているように、ctypesの標準の Structure および Union 機能を使用できます。 Pythonでctype構造+ユニオンを適切に宣言しますか? - スタックオーバーフロー

たとえば、バイトの最下位 4 ビットを個別に操作するには、LittleEndianStructure で最下位から最上位の順に名前を付けます。共用体を使用して byte または int と同じデータへのアクセスを提供し、データを通信プロトコルの内外に移動できるようにします。この場合、flags.asbyteフィールドを介して行われます。

import ctypes
c_uint8 = ctypes.c_uint8

class Flags_bits(ctypes.LittleEndianStructure):
    _fields_ = [
            ("logout", c_uint8, 1),
            ("userswitch", c_uint8, 1),
            ("suspend", c_uint8, 1),
            ("idle", c_uint8, 1),
        ]

class Flags(ctypes.Union):
    _fields_ = [("b", Flags_bits),
                ("asbyte", c_uint8)]

flags = Flags()
flags.asbyte = 0xc

print(flags.b.idle)
print(flags.b.suspend)
print(flags.b.userswitch)
print(flags.b.logout)

4 つのビット (ここでは最上位から始めて印刷しましたが、これは印刷するとより自然に見えます) は 1、1、0、0、つまりバイナリの 0xc です。

于 2012-07-14T06:02:45.523 に答える
32

Bitarrayは、最近同様のニーズがあったときに見つけた最良の答えでした。これは C 拡張であり (純粋な Python である BitVector よりもはるかに高速です)、そのデータを実際のビットフィールドに格納します (したがって、要素ごとに 1 バイトを使用するように見える numpy ブール配列よりも 8 倍のメモリ効率があります)。

于 2008-09-27T08:20:43.577 に答える
15

最近バージョン 2.0 になったbitstringモジュールを見てください。バイナリ データはバイト配列としてコンパクトに格納され、簡単に作成、変更、分析できます。

BitStringバイナリ、8 進数、16 進数、整数 (ビッグまたはリトル エンディアン)、文字列、バイト、浮動小数点数、ファイルなどからオブジェクトを作成できます。

a = BitString('0xed44')
b = BitString('0b11010010')
c = BitString(int=100, length=14)
d = BitString('uintle:16=55, 0b110, 0o34')
e = BitString(bytes='hello')
f = pack('<2H, bin:3', 5, 17, '001') 

次に、単純な関数またはスライス表記を使用してそれらを分析および変更できます-ビットマスクなどについて心配する必要はありません.

a.prepend('0b110')
if '0b11' in b:
    c.reverse()
g = a.join([b, d, e])
g.replace('0b101', '0x3400ee1')
if g[14]:
    del g[14:17]
else:
    g[55:58] = 'uint:11=33, int:9=-1'

ビット位置の概念もあるので、必要に応じてファイルやストリームのように扱うことができます。プロパティは、ビット データのさまざまな解釈を与えるために使用されます。

w = g.read(10).uint
x, y, z = g.readlist('int:4, int:4, hex:32')
if g.peek(8) == '0x00':
    g.pos += 10

さらに、標準のビット単位のバイナリ演算子、パック、アンパック、エンディアンなどもサポートされています。最新バージョンは Python 2.7 および 3.x 用で、純粋な Python ですが、メモリと速度の点で適度に最適化されています。

于 2009-10-15T20:43:54.270 に答える
9

それぞれの値を 2 の累乗で表します。

testA = 2**0
testB = 2**1
testC = 2**3

次に、値を true に設定します。

table = table | testB

値を false に設定するには:

table = table & (~testC)

値をテストするには:

bitfield_length = 0xff
if ((table & testB & bitfield_length) != 0):
    print "Field B set"

これが意味をなさない場合は、16 進数表現をもう少し深く掘り下げてください。これは基本的に、埋め込み C アプリケーションでもブール値フラグを追跡する方法です (メモリが限られている場合)。

于 2008-11-05T15:30:33.933 に答える
7

二項ビット演算子 !、&、|、^、>>、および << を使用します。それらは非常にうまく機能し、基礎となる C に直接実装されます。これは通常、基礎となるハードウェア上に直接存在します。

于 2008-09-27T13:26:06.400 に答える
5

BitVector パッケージが必要な場合があります。私のpythonインストールには組み込まれていませんが、pythonサイトで簡単に追跡できます。

現在のバージョンのhttps://pypi.python.org/pypi/BitVector 。

于 2008-09-27T03:03:16.880 に答える
4

NumPy には、ビットフィールドを作成するために使用できる配列インターフェイスモジュールがあります。

于 2008-09-27T02:52:13.740 に答える
2

ビットフィールドが短い場合は、おそらくstruct moduleを使用できます。それ以外の場合は、配列モジュールのラッパーのようなものをお勧めします。

また、 ctypes モジュールにはbitfieldsが含まれていますが、私自身は使用したことがありません。emptorに注意してください。

于 2008-09-27T08:41:05.383 に答える
1

int (または long int) を使用して bool の配列 (または整数のセット) として表現する場合は、 http ://sourceforge.net/projects/pybitop/files/ を ご覧ください。

ビットフィールドの long int への挿入/抽出を提供します。最上位または最下位の「1」ビットを見つける。すべての 1 を数えます。ビット反転; 純粋な python ではすべて可能ですが、C でははるかに高速です。

于 2010-09-16T21:01:07.227 に答える