How to split a byte string into separate bytes in python
Solution 1
You can use slicing on byte
objects:
>>> value = b'\x00\x01\x00\x02\x00\x03'
>>> value[:2]
b'\x00\x01'
>>> value[2:4]
b'\x00\x02'
>>> value[-2:]
b'\x00\x03'
When handling these frames, however, you probably also want to know about memoryview()
objects; these let you interpret the bytes as C datatypes without any extra work on your part, simply by casting a 'view' on the underlying bytes:
>>> mv = memoryview(value).cast('H')
>>> mv[0], mv[1], mv[2]
256, 512, 768
The mv
object is now a memory view interpreting every 2 bytes as an unsigned short; so it now has length 3 and each index is an integer value, based on the underlying bytes.
Solution 2
Here is a way that you can split the bytes into a list:
data = b'\x00\x00\x00\x00\x00\x00'
info = [data[i:i+2] for i in range(0, len(data), 2)]
print info
gives the result:
['\x00\x00', '\x00\x00', '\x00\x00']
Solution 3
You are actually asking about serialization/deserialization. Use struct.pack and struct.unpack (https://docs.python.org/3/library/struct.html). This gives you nice primitives to do both unpacking and things like endian swapping. For example:
import struct
struct.unpack("<H",b"\x00\x01") # unpacks 2 byte little endian unsigned int
struct.unpack(">l",b"\x00\x01\x02\x03") # unpacks 4 byte big endian signed int
Note that your example splits 2 byte words, not bytes.
Since this question is also coming up in searches about splitting binary strings:
value = b'\x00\x01\x00\x02\x00\x03'
split = [value[i] for i in range (0, len(value))]
# now you can modify, for example:
split[1] = 5
# put it back together
joined = bytes(split)
![Razzad777](https://i.stack.imgur.com/Mzriv.jpg?s=256&g=1)
Razzad777
I'm relatively new to programming having only spent just 3 years studying it, am hoping to progress into a career involving programming in some way, however am not sure what.
Updated on July 09, 2022Comments
-
Razzad777 almost 2 years
Ok so I've been using python to try create a waveform image and I'm getting the raw data from the
.wav
file usingsong = wave.open()
andsong.readframes(1)
, which returns :b'\x00\x00\x00\x00\x00\x00'
What I want to know is how I split this into three separate bytes, e.g.
b'\x00\x00'
,b'\x00\x00'
,b'\x00\x00'
because each frame is 3 bytes wide so I need the value of each individual byte to be able to make a wave form. I believe that's how I need to do it anyway.-
wwii over 10 years
-
-
Bachsau about 5 yearsThis lookst like the cleanest solution, as it does the work with as less copying and counting as possible. Using
struct.iter_unpack
you can even loop over large blocks of repeating structures.