我有一个长的字节数组。
什么是将其转换为2字节整数列表的最佳方法?
barray=b'\x00\xfe\x4b\x00...
什么是将其转换为2字节整数列表的最佳方法?
struct
包来实现这个功能:from struct import unpack
tuple_of_shorts = unpack('h'*(len(barray)//2),barray)
'H'
替代:tuple_of_shorts = unpack('H'*(len(barray)//2),barray)
>>> struct.unpack('h'*(len(barray)//2),barray)
(-512, 75)
>>> struct.unpack('H'*(len(barray)//2),barray)
(65024, 75)
如果你想要使用大端(big endian)或小端(little endian)格式,在规格说明中可以放置一个>
(表示大端)或<
(表示小端)。例如:
# Big endian
tuple_of_shorts = unpack('>'+'H'*(len(barray)//2),barray) # unsigned
tuple_of_shorts = unpack('>'+'h'*(len(barray)//2),barray) # signed
# Little endian
tuple_of_shorts = unpack('<'+'H'*(len(barray)//2),barray) # unsigned
tuple_of_shorts = unpack('<'+'h'*(len(barray)//2),barray) # signed
生成:
>>> unpack('>'+'H'*(len(barray)//2),barray) # big endian, unsigned
(254, 19200)
>>> unpack('>'+'h'*(len(barray)//2),barray) # big endian, signed
(254, 19200)
>>> unpack('<'+'H'*(len(barray)//2),barray) # little endian, unsigned
(65024, 75)
>>> unpack('<'+'h'*(len(barray)//2),barray) # little endian, signed
(-512, 75)
import struct
count = len(barray)/2
integers = struct.unpack('H'*count, barray)
根据字节序的不同,您可能需要在拆包格式前加上<
或>
。而根据有无符号,使用h
或H
。
struct
库转换数组还允许您为格式说明符中的每个项指定重复计数。例如,4H
将与使用 HHHH
相同。import struct
barray = b'\x00\xfe\x4b\x00\x4b\x00'
integers = struct.unpack('{}H'.format(len(barray)/2), barray)
print(integers)
(65024, 75, 75)
如果内存效率是一个问题,您可以考虑使用 array.array
:
>>> barr = b'\x00\xfe\x4b\x00'
>>> import array
>>> short_array = array.array('h', barr)
>>> short_array
array('h', [-512, 75])
这就像是一个占用空间更小的原始数组,附带有一个面向对象的包装器,因此它支持像 list
上一样的序列类型方法,例如 .append
、.pop
和切片!
>>> short_array[:1]
array('h', [-512])
>>> short_array[::-1]
array('h', [75, -512])
bytes
对象变得非常简单:>>> short_array
array('h', [-512, 75])
>>> short_array.tobytes()
b'\x00\xfeK\x00'
请注意,如果您需要与本机字节顺序相反的字节顺序,请使用就地 byteswap
方法:
>>> short_array.byteswap()
>>> short_array
array('h', [254, 19200])