40

How can I declare a bit array of a very large size, say 6 million bits?

3
  • 13
    What are you trying to achieve? Commented Jul 26, 2012 at 12:22
  • 5
    This could be used for something like a bitmap. Commented Apr 30, 2014 at 16:38
  • See also stackoverflow.com/questions/2147848/… -- hesitant to mark as duplicate. Commented May 26, 2016 at 5:16

6 Answers 6

46
from bitarray import bitarray

a = bitarray(2**20)

You can check out more info about this module at http://pypi.python.org/pypi/bitarray/

Sign up to request clarification or add additional context in comments.

3 Comments

bitarray does not seem to be in the standard python, but is instead a feature offered by pypy.
I think you mean pip
I think you mean “included in PyPI”, the Python Package Index. :p
28

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

11

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

11

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

This is not quite the same when it comes to the length of the array. For example, bitarrays '000' and '0' should be distinct.
First, one can encapsulate the logic inside the class. Second, I thought of "1000" where the leading 1 determines the array's length. Thus, 1000 is an array with three slots, not four as one might think. With this little twist, it is fine. As I said the implementation may be tricky but it should work.
Yes, the leading 1 is a little hacky for finding the array length and getting the raw bits out. But it's an interesting memory optimization.
You can actually use a different base, say three, for three options. It takes some math to store them but it is doable.
This is not a bit array. You're using shift operations to mimic the results. Readability is terrible, this would not pass a code quality review. Unclear and hacky, too prone to mistakes.
10

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   

1 Comment

I updated pip beforehand see link Then execute python -m pip install bitarray on Windows.
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.