Python Forum
Convert list of integers to bit-mapped byte
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Convert list of integers to bit-mapped byte
#1
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.
Reply
#2
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]
Reply
#3
Or, if you prefer tiny functions:
bitmap = lambda items: [1 if ndx in items else 0 for ndx in range(8)]
Reply
#4
@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)
Reply
#5
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.
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#6
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
Reply
#7
Yes, it was not clear if the first is 0
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#8
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?
Reply
#9
Bitwise operations are faster.
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#10
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.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  No matter what I do I get back "List indices must be integers or slices, not list" Radical 4 1,172 Sep-24-2023, 05:03 AM
Last Post: deanhystad
  Timestamp of file changes if a share mapped to a server…. tester_V 34 3,949 Jul-04-2023, 05:19 AM
Last Post: tester_V
  Response.json list indices must be integers or slices, not str [SOLVED] AlphaInc 4 6,413 Mar-24-2023, 08:34 AM
Last Post: fullytotal
Question How to append integers from file to list? Milan 8 1,452 Mar-11-2023, 10:59 PM
Last Post: DeaD_EyE
  convert string to float in list jacklee26 6 1,914 Feb-13-2023, 01:14 AM
Last Post: jacklee26
  Error "list indices must be integers or slices, not str" dee 2 1,464 Dec-30-2022, 05:38 PM
Last Post: dee
  convert a list to links Pir8Radio 3 1,099 Nov-28-2022, 01:52 PM
Last Post: Pir8Radio
  convert this List Comprehensions to loop jacklee26 8 1,512 Oct-21-2022, 04:25 PM
Last Post: deanhystad
  read a text file, find all integers, append to list oldtrafford 12 3,584 Aug-11-2022, 08:23 AM
Last Post: Pedroski55
  Convert list to interger Clives 5 1,634 May-09-2022, 12:53 PM
Last Post: deanhystad

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020