Frage

Ich brauche eine kompakte Darstellung eines Arrays von booleans, ist Python einen eingebauten bitfield Typ oder werde ich eine alternative Lösung finden muß?

War es hilfreich?

Lösung

BitArray war die beste Antwort, die ich gefunden, wenn ich ein ähnliches Bedürfnis vor kurzem hatte. Es ist eine C-Erweiterung (so viel schneller als Bitvektor, die reine Python ist) und speichert seine Daten in einem tatsächlichen bitfield (es ist also acht Mal mehr Speicher effizienter als ein numpy boolean-Array, das ein Byte pro Element verwendet wird.)

Andere Tipps

Wenn Sie in erster Linie in der Lage sein wollen, um Ihre Bit-Felder zu benennen und sie leicht zu manipulieren, zum Beispiel mit Fahnen als einzelne Bits in einem Kommunikationsprotokoll dargestellt zu arbeiten, dann können Sie die Standardstruktur und Union Features von ctypes , wie unter

Sie sollten einen Blick auf dem bitstring -Modul, das vor kurzer Version 2.0 erreicht hat . Die binären Daten werden kompakt als Byte-Array gespeichert und einfach erstellt werden können, modifiziert und analysiert.

Sie können BitString Objekte aus Binär-, hex, ganze Zahlen (groß oder Little-Endian), Streicher, Bytes, Schwimmern, Dateien und vieles mehr.

erstellen
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') 

Sie können dann analysieren und sie mit einfachen Funktionen oder Slice-Notation ändern -. Keine Notwendigkeit, sich Sorgen zu machen über Bitmasken etc

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'

Es gibt auch ein Konzept einer Bit-Position, so dass Sie es wie eine Datei behandeln können oder streamen, wenn das für Dich nützlich ist. Die Eigenschaften werden verwendet, um unterschiedliche Interpretationen der Bit-Daten zu geben.

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

Außerdem gibt es Unterstützung für die Standard-bitweise binären Operatoren, Verpackung, Auspacken, endianness und vieles mehr. Die neueste Version ist für Python 2.7 und 3.x, und obwohl es rein ist Python es ist recht gut in Bezug auf Speicher und Geschwindigkeit optimiert.

Ich benutze die binären bitweise Operatoren &, |! ^, >> und <<. Sie arbeiten wirklich gut und werden direkt in der zugrunde liegenden C implementiert, die auf der zugrunde liegenden Hardware in der Regel direkt ist.

Sie sind jede Ihrer Werte als Zweierpotenz:

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

Sie dann einen Wert setzen true:

table = table | testB

ein Wert false ein:

table = table & (~testC)

für einen Wert testen:

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

ein wenig tiefer in hexadezimale Darstellung Dig, wenn dies nicht Sinn machen. Dies ist im Grunde, wie Sie den Überblick über Ihren boolean Flags in einer eingebetteten C-Anwendung halten als auch (wenn Sie limitted Speicher haben).

Das Bitvektor Paket kann sein, was Sie brauchen. Es ist nicht in meiner Python-Installation gebaut, aber leicht auf der Python-Website aufzuspüren.

https://pypi.python.org/pypi/BitVector für die aktuelle Version .

NumPy hat einen Array Schnittstelle Modul, das Sie eine bitfield machen verwenden können.

Wenn Ihr bitfield kurz ist, können Sie wahrscheinlich die Struktur Modul . Sonst würde ich so etwas wie ein Wrapper um der Array-Modul empfehlen.

Auch dann, wenn das ctypes Modul enthalten bitfields , aber ich habe es mir nie. Caveat emptor .

Wenn Sie verwenden Ints wollen (oder lange Ints) als Arrays von bools darzustellen (oder als Mengen von ganzen Zahlen), werfen Sie einen Blick auf http://sourceforge.net/projects/pybitop/files/

Es bietet Insert / Auszug bitfields in langen Ints; Suche nach der höchstwertigen oder niedrigstwertigen ‚1‘ Bit; Zählen alle 1'en; Bit-Umkehr; Sachen wie das, was alles möglich in reinem Python ist aber viel schneller in C.

Für meist aufeinanderfolgende Bits gibt es die https://pypi.org/project/range_set/ Modul, das API kompatibel zu Python eingebauter in set ist. Wie der Name schon sagt, speichert es die Bits als Beginn / Ende-Paare.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top