如何将字节字符串分割成单独的部分

46

我一直在尝试创建波形图像,使用 song = wave.open()song.readframes(1).wav 文件中获取原始数据,返回如下:

b'\x00\x00\x00\x00\x00\x00'

我该如何将它分成三个独立的部分,例如 b'\x00\x00'b'\x00\x00'b'\x00\x00'?因为每个帧由 3 部分组成(每部分为 2 个字节宽),所以我需要每个单独部分的值才能制作波形。


wave.readframes 返回什么? - wwii
3个回答

74

您可以在 byte 对象上使用切片:

>>> value = b'\x00\x01\x00\x02\x00\x03'
>>> value[:2]
b'\x00\x01'
>>> value[2:4]
b'\x00\x02'
>>> value[-2:]
b'\x00\x03'

然而,在处理这些帧时,您可能还想了解 memoryview() 对象;它们允许您将字节解释为C数据类型,而无需进行任何额外的工作,只需在底层字节上进行“视图”转换即可:

>>> mv = memoryview(value).cast('H')
>>> mv[0], mv[1], mv[2]
256, 512, 768

mv 对象现在是一个内存视图,将每2个字节解释为无符号短整型; 因此它现在的长度为3,并且每个索引是一个整数值,基于底层的字节。


36

以下是一种将字节拆分到列表中的方法:

data = b'\x00\x00\x00\x00\x00\x00'
info = [data[i:i+2] for i in range(0, len(data), 2)]
print info

得到的结果为:

['\x00\x00', '\x00\x00', '\x00\x00']

6

您实际上是在询问序列化/反序列化。使用struct.pack和struct.unpack(https://docs.python.org/3/library/struct.html)。这为您提供了很好的原语来进行拆包以及类似于字节序交换的操作。例如:

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

请注意您的示例分隔2字节单词而不是字节。
由于这个问题也出现在关于拆分二进制字符串的搜索中:
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)

1
这似乎是最干净的解决方案,因为它尽可能地减少了复制和计数的工作量。使用 struct.iter_unpack,您甚至可以循环遍历大型重复结构块。 - Bachsau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接