I need a compact representation of an array of booleans, does Python have a builtin bitfield type or will I need to find an alternate solution?
If you mainly want to be able to name your bit fields and easily manipulate them, e.g. to work with flags represented as single bits in a communications protocol, then you can use the standard Structure and Union features of ctypes, as described at How Do I Properly Declare a ctype Structure + Union in Python? - Stack Overflow
For example, to work with the 4 least-significant bits of a byte individually, just name them from least to most significant in a LittleEndianStructure. You use a union to provide access to the same data as a byte or int so you can move the data in or out of the communication protocol. In this case that is done via the flags.asbyte
field:
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)
The four bits (which I've printed here starting with the most significant, which seems more natural when printing) are 1, 1, 0, 0, i.e. 0xc in binary.
Bitarray was the best answer I found, when I recently had a similar need. It's a C extension (so much faster than BitVector, which is pure python) and stores its data in an actual bitfield (so it's eight times more memory efficient than a numpy boolean array, which appears to use a byte per element.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With