Search code examples
python-3.xarraysswapmodbus

How do I rearrange bytes in a bytearray in Python?


I am new to python and doing embedded-related work (most of my programming experience has been using C).

I am reading a four-byte float into a bytearray from a serial port but instead of the normal little-endian order DCBA, it is encoded as CDAB. Or it may be encoded as BADC. (where A is most significant byte and D is LSB). What is the correct way of swapping bytes around in a bytearray?

For example, I have

tmp=bytearray(pack("f",3.14))

I want to be able to arbitrarily arrange the bytes in tmp, and then unpack() it back into a float.

Things like this seem essential when doing anything related to embedded systems, but either I am googling it wrong or no clear answer is out there (yet!).

edit: sure, I can do this:

from struct import *

def modswap(num):

    tmp=bytearray(pack("f",num))
    res=bytearray()
    res.append(tmp[2])
    res.append(tmp[3])
    res.append(tmp[0])
    res.append(tmp[1])
    return unpack('f',res)


def main():
    print(modswap(3.14))

but there has to be a better way...

Ideally, I would like to be able to slice and re-concatenate as I please, or even replace a slice at a time if possible.


Solution

  • You can swizzle in one step:

    from struct import pack,unpack
    
    def modswap(num):
        tmp=bytearray(pack("f",num))
        tmp[0],tmp[1],tmp[2],tmp[3] = tmp[2],tmp[3],tmp[0],tmp[1]
        return unpack('f',tmp)
    

    You can modify a slice of a byte array:

    >>> data = bytearray(b'0123456789')
    >>> data[3:7] = data[5],data[6],data[3],data[4]
    >>> data
    bytearray(b'0125634789')