J'ai besoin d'une représentation compacte d'un tableau de booléens. Python possède-t-il un type de champ de bits intégré ou dois-je trouver une autre solution ?
Est BitArray
disponible pour l'installation sur Windows ?
J'ai besoin d'une représentation compacte d'un tableau de booléens. Python possède-t-il un type de champ de bits intégré ou dois-je trouver une autre solution ?
Si vous souhaitez principalement être en mesure de nommer vos champs de bits et de les manipuler facilement, par exemple pour travailler avec des drapeaux représentés sous forme de bits uniques dans un protocole de communication, vous pouvez utiliser les fonctions standard Structure et Union de l'interface utilisateur. ctypes comme décrit à Comment déclarer correctement une structure ctype + Union en Python ? - Stack Overflow
Par exemple, pour travailler individuellement avec les 4 bits les moins significatifs d'un octet, il suffit de les nommer du moins au plus significatif dans une LittleEndianStructure. Vous utilisez une union pour fournir un accès aux mêmes données qu'un octet ou un int afin de pouvoir déplacer les données dans ou hors du protocole de communication. Dans ce cas, cela se fait par le biais de la fonction flags.asbyte
champ :
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)
Les quatre bits (que j'ai imprimés ici en commençant par le plus significatif, ce qui semble plus naturel à l'impression) sont 1, 1, 0, 0, c'est-à-dire 0xc en binaire.
Réseau binaire a été la meilleure réponse que j'ai trouvée, lorsque j'ai eu récemment un besoin similaire. C'est une extension C (donc beaucoup plus rapide que BitVector, qui est purement python) et stocke ses données dans un champ de bits réel (donc c'est huit fois plus efficace en mémoire qu'un tableau booléen numpy, qui semble utiliser un octet par élément).
On dirait que BitArray
est facilement disponible pour une installation sur Linux mais rien sur la page ne suggère une installation PIP pour Windows. C'est dommage...
Ce bon vieux Christoph Gohlke, je dis Construction d'un réseau de bits sous Windows :) Le site peut dire "Unofficial Windows Binaries for Python Extension Packages" mais j'ai utilisé des tas de paquets et je n'ai jamais eu de problème.
Vous devriez jeter un coup d'œil à la chaîne de bits qui a récemment atteint la version 2.0. Les données binaires sont stockées de manière compacte sous forme de tableau d'octets et peuvent être facilement créées, modifiées et analysées.
Vous pouvez créer BitString
d'objets binaires, octaux, hexagonaux, entiers (big ou little endian), chaînes de caractères, octets, flottants, fichiers et autres.
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')
Vous pouvez ensuite les analyser et les modifier à l'aide de fonctions simples ou de la notation en tranches - sans avoir à vous soucier des masques de bits, 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'
Il existe également un concept de position binaire, de sorte que vous pouvez le traiter comme un fichier ou un flux si cela vous est utile. Les propriétés sont utilisées pour donner différentes interprétations des données binaires.
w = g.read(10).uint
x, y, z = g.readlist('int:4, int:4, hex:32')
if g.peek(8) == '0x00':
g.pos += 10
De plus, il prend en charge les opérateurs binaires standard, l'empaquetage, le dépaquetage, l'endiannage et bien plus encore. La dernière version est compatible avec Python 2.6 à 3.1, et bien qu'il s'agisse de Python pur, il est raisonnablement bien optimisé en termes de mémoire et de vitesse.
Représentez chacune de vos valeurs comme une puissance de deux :
testA = 2**0
testB = 2**1
testC = 2**3
Ensuite, pour définir une valeur vraie :
table = table | testB
Pour définir une valeur fausse :
table = table & (~testC)
Pour tester une valeur :
bitfield_length = 0xff
if ((table & testB & bitfield_length) != 0):
print "Field B set"
Creusez un peu plus loin dans la représentation hexadécimale si cela n'a pas de sens pour vous. C'est aussi la façon dont vous gardez la trace de vos drapeaux booléens dans une application C embarquée (si vous avez une mémoire limitée).
Le paquet BitVector est peut-être ce dont vous avez besoin. Il n'est pas intégré à mon installation python, mais il est facile à trouver sur le site python.
http://pypi.python.org/pypi/BitVector/1.5.1 est la version actuelle à ce jour.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
0 votes
Pour les cas où le terme est ambigu, j'en déduis que vous voulez les types de fonctionnalités disponibles dans les champs de bits C, ou telles que décrites ici ? fr.wikipedia.org/wiki/Bit_field