Question

I need to split a 16-bit unsigned integer into an array of bytes (i.e. array.array('B')) in python.

For example:

>>> reg_val = 0xABCD
[insert python magic here]
>>> print("0x%X" % myarray[0])
0xCD
>>> print("0x%X" % myarray[1])
0xAB

The way I'm currently doing it seems very complicated for something so simple:

>>> import struct
>>> import array
>>> reg_val = 0xABCD
>>> reg_val_msb, reg_val_lsb = struct.unpack("<BB", struct.pack("<H", (0xFFFF & reg_val)))
>>> myarray = array.array('B')
>>> myarray.append(reg_val_msb)
>>> myarray.append(reg_val_lsb)

Is there a better/more efficient/more pythonic way of accomplishing the same thing?

Was it helpful?

Solution

(using python 3 here, there are some nomenclature differences in 2)

Well first, you could just leave everything as bytes. This is perfectly valid:

reg_val_msb, reg_val_lsb = struct.pack('<H', 0xABCD)

bytes allows for "tuple unpacking" (not related to struct.unpack, tuple unpacking is used all over python). And bytes is an array of bytes, which can be accessed via index as you wanted.

b = struct.pack('<H',0xABCD)

b[0],b[1]
Out[52]: (205, 171)

If you truly wanted to get it into an array.array('B'), it's still rather easy:

ary = array('B',struct.pack('<H',0xABCD))
# ary = array('B', [205, 171])

print("0x%X" % ary[0])
# 0xCD

OTHER TIPS

For non-complex numbers you can use divmod(a, b), which returns a tuple of the quotient and remainder of arguments.

The following example uses map() for demonstration purposes. In both examples we're simply telling divmod to return a tuple (a/b, a%b), where a=0xABCD and b=256.

>>> map(hex, divmod(0xABCD, 1<<8)) # Add a list() call here if your working with python 3.x
['0xab', '0xcd']

# Or if the bit shift notation is distrubing:
>>> map(hex, divmod(0xABCD, 256))

Or you can just place them in the array:

>>> arr = array.array('B')
>>> arr.extend(divmod(0xABCD, 256))
>>> arr
array('B', [171, 205])

You can write your own function like this.

def binarray(i):
    while i:
        yield i & 0xff
        i = i >> 8

print list(binarray(0xABCD))
#[205, 171]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top