How can I declare a bit array of a very large size, say 6 million bits?
-
13What are you trying to achieve?ThiefMaster– ThiefMaster2012-07-26 12:22:07 +00:00Commented Jul 26, 2012 at 12:22
-
5This could be used for something like a bitmap.SJP– SJP2014-04-30 16:38:17 +00:00Commented Apr 30, 2014 at 16:38
-
See also stackoverflow.com/questions/2147848/… -- hesitant to mark as duplicate.tripleee– tripleee2016-05-26 05:16:15 +00:00Commented May 26, 2016 at 5:16
6 Answers
from bitarray import bitarray
a = bitarray(2**20)
You can check out more info about this module at http://pypi.python.org/pypi/bitarray/
The bitstring module may help:
from bitstring import BitArray
a = BitArray(6000000)
This will take less than a megabyte of memory, and it's easy to set, read, slice and interpret bits. Unlike the bitarray module it's pure Python, plus it works for Python 3.
See the documentation for more details.
Comments
This one-liner converts bytes to a list of True/False bit values. Might be not performant for 6M bits but for small flags it should be fine and does not need additional dependencies.
>>> flags = bytes.fromhex(b"beef")
>>> bits = [flags[i//8] & 1 << i%8 != 0 for i in range(len(flags) * 8)]
>>> print(bits)
[False, True, True, True, True, True, False, True, True, True, True, True, False, True, True, True]
Comments
Quite easily
bitarray60000 = 1<<60000
With that, you can use bitshift operator to your heart content. For instance, position 2 set True would be:
bitarray60000 | 1<<2
Getting bit from position 2
bitarray60000 & 1<<2
I guess the idea is quite simple. Though some operations might be tricky.
5 Comments
Get the bitarray module using
pip install bitarray
Then, this code will create a bit array of size 6 million,
from bitarray import bitarray
bit_array = bitarray(6000000)
You can initialize all the bits to zero using
bit_array.setall(0)
To set a particular bit, say bit number 25, to 1, do this:
bit_array[25]=1
If you want to avoid dependencies on third party packages, then it's pretty easy to roll your own clone of bitarray. Today I needed something that resembles array.array, and I only needed iteration and (little-endian) tobytes, so the following was sufficient:
class BitArray:
def __init__(self, iterable):
self._arr = list(map(bool, iterable))
def __iter__(self):
return iter(self._arr)
def tobytes(self):
return bytes(
sum((bit << i for (i, bit) in enumerate(batch)), 0)
for batch in itertools.batched(self._arr, 8))
If space consumption is a concern, then the following yields a more compact representation:
class BitArray:
def __init__(self, iterable):
last_i = 7
self._blob = bytes(
sum((bool(bit) << (last_i := i)
for (i, bit) in enumerate(batch)), 0)
for batch in itertools.batched(iterable, 8))
self._bits_in_last_byte = (last_i + 1) & 7
def __iter__(self):
return itertools.chain(
(bool((x >> i) & 1) for x in self._blob[:-1] for i in range(8)),
(bool((self._blob[-1] >> i) & 1)
for i in range(self._bits_in_last_byte)))
def tobytes(self):
return self._blob