rRr
rRr

Reputation: 408

Python turn array of booleans to binary

I am preparing new driver for one of our new hardware devices.

One of the option to set it up, is where one byte, has 8 options in it. Every bite turns on or off something else.

So, basically what I need to do is, take 8 zeros or ones and create one byte of them.

What I did is, I have prepares helper function for it:

@staticmethod
def setup2byte(setup_array):
    """Turn setup array (of 8 booleans) into byte"""
    data = ''
    for b in setup_array:
        data += str(int(b))
    return int(data, 2)

Called like this:

    settings = [echo, reply, presenter, presenter_brake, doors_action, header, ticket_sensor, ext_paper_sensor]
    data = self.setup2byte(settings)
    packet = "{0:s}{1:s}{2:d}{3:s}".format(CONF_STX, 'P04', data, ETX)
    self.queue_command.put(packet)

and I wonder if there is easier way how to do it. Some built in function or something like that. Any ideas?

Upvotes: 5

Views: 6863

Answers (4)

Wör Du Schnaffzig
Wör Du Schnaffzig

Reputation: 1051

I think it is neither necessary to create an intermediate string array, a for-loop nor using a slow power function.

The solution can be crunched down to a one liner using sum and map and the binary shift operator.

settings = [False, True, False, True, True, False, False, True]
x = sum(map(lambda x: x[1] << x[0], enumerate(settings)))
print(bin(x))

> 0b10011010

Remark: The first element in the array has the lowest prio, else the settings would need to be reversed.

Upvotes: 2

talz
talz

Reputation: 1200

that's basically what you are already doing, but shorter:

data = int(''.join(['1' if i else '0' for i in settings]), 2)

But here is the answer you are looking for: Bool array to integer

Upvotes: 1

user3598726
user3598726

Reputation: 1081

I think the previous answers created 8 bytes. This solution creates one byte only

settings = [False,True,False,True,True,False,False,True]
# LSB first


integerValue = 0
# init value of your settings
for idx, setting in enumerate(settings):
    integerValue += setting*2**idx


# initialize an empty byte
mybyte = bytearray(b'\x00')
mybyte[0] =integerValue
print (mybyte)

For more example visit this great site: binary python

Upvotes: 0

Jared Smith
Jared Smith

Reputation: 22030

I believe you want this:

convert2b = lambda ls: bytes("".join([str(int(b)) for b in ls]), 'utf-8')

Where ls is a list of booleans. Works in python 2.7 and 3.x. Alternative more like your original:

convert2b = lambda ls: int("".join([str(int(b)) for b in ls]), 2)

Upvotes: 1

Related Questions