Python Forum
Convert list of integers to bit-mapped byte - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Convert list of integers to bit-mapped byte (/thread-5853.html)

Pages: 1 2


Convert list of integers to bit-mapped byte - eccles - Oct-24-2017

I have a list of integers that represents solenoid numbers to turn ON.
For example, the list [1, 3, 4, 7], where:
- the number “1” represents the 1st solenoid, "3 the 3rd solenoid etc,
- this list means turn solenoids 1, 3, 4 and 7 ON, all the others OFF.

I need to output this as a bit-mapped byte where each bit (0 to 7) represents solenoids 1 to 8 respectively. So for the above case this should give a byte value of

01001101 in binary (or 0x4C in hexadecimal or 76 in decimal notation)

Is there a Python library that will handle this for me, or does anyone have a code snippet that they can share please?

Thank you.


RE: Convert list of integers to bit-mapped byte - nilamo - Oct-24-2017

Quote:Is there a Python library that will handle this for me
Luckily, this isn't javascript.  We don't have a repository of functions that are only two lines each.


Try this: create a list of 8 items, and set all of them to zero.  Each item in your list of solenoids you want on, is then the index, so just set it to one.

Something like this:
>>> def bitmap(on_solenoids):
...   bits = [0 for _ in range(8)]
...   for solenoid in on_solenoids:
...     bits[solenoid] = 1
...   return bits
...
>>> bitmap([1, 3, 4, 7])
[0, 1, 0, 0, 1, 1, 0, 1]



RE: Convert list of integers to bit-mapped byte - nilamo - Oct-24-2017

Or, if you prefer tiny functions:
bitmap = lambda items: [1 if ndx in items else 0 for ndx in range(8)]



RE: Convert list of integers to bit-mapped byte - eccles - Oct-24-2017

@nilamo
Thanks for the very speedy response!

Nicely written and easy to understand.

I probably wasn't clear enough in my post. What I'd actually like to return from the function is just a single variable which has the bits set appropriately rather than a list of bits.
i.e. for the list example of [1, 3, 4, 7], the function should return a single variable with the value = 76 (decimal notation).

For the electronic pythonists, the idea is that I would send that single byte out via the SPI bus to a shift register in the hardware.

Sorry, the decimal format result for the sample list given should be 77, not 76.

So to summarize :
Input:
- a list of up to 8 integers
- each integer value in the list will be in the range of 1 to 8

Required Output:
- a variable with a value of 0 to 255 (i.e. a byte)


RE: Convert list of integers to bit-mapped byte - wavic - Oct-24-2017

Hello!
Here is how to set the n-th bit to 1
def set_bit(num, bit_pos):
    if bit_pos == 1:
        return num | 1
    else:
        return num | ( 1<<(bit_pos - 1))

selenoids = 0
for n in [1,3,4,7]:
    selenoids = set_bit(selenoids, n)
To unset the n-th bit just copy the same function, change the name to unset_bit and replace '|' with '&'. The first one is bitwise OR and the second is AND.


RE: Convert list of integers to bit-mapped byte - Larz60+ - Oct-25-2017

I assumed first io pin was 0, so 0 to 7
I did it a bit differently:
def list_to_bin(mylist):
    newx = 1
    mybyte = 0
    for num in mylist:
        if num:
            newx = 1 << (num - 1)
            mybyte = mybyte | newx
    print('{0:02x}'.format(mybyte))
list_to_bin([1, 3, 4 ,7])
result:
Output:
4d



RE: Convert list of integers to bit-mapped byte - wavic - Oct-25-2017

Yes, it was not clear if the first is 0


RE: Convert list of integers to bit-mapped byte - eccles - Oct-25-2017

Thanks for taking the time to reply.

After reviewing the replies and reading some documentation I have come up with another snippet. This code isn't the most Pythonic but should be easy to understand.

>>> def integer_list_to_byte(integer_list):
	control_byte = 0
	for element in integer_list:
		control_byte += pow(2, element- 1)
	return control_byte

>>> integer_list_to_byte([1, 3, 4, 7])
77
Alternatively, using the shift operator:

>>> def integer_list_to_byte(integer_list):
	control_byte = 0
	for element in integer_list:
		control_byte += 1 << (element- 1)
	return control_byte

>>> integer_list_to_byte([1, 3, 4, 7])
77
Is there any difference in execution speed?


RE: Convert list of integers to bit-mapped byte - wavic - Oct-25-2017

Bitwise operations are faster.


RE: Convert list of integers to bit-mapped byte - nilamo - Oct-25-2017

Quote: Is there any difference in execution speed?

Unless you're calling that function millions of times each second, you shouldn't worry about speed.  The difference will be so minimal, that you likely will not notice.  Instead, use whatever makes sense to you, and is clear about what's going on.