是否有一种简单的方法可以读取这些整数?我希望使用内置方法,但是我认为可以进行一些位操作。干杯
编辑我想到了另一种方法来完成此操作,该方法与下面的方法不同,我认为这更清楚。它在另一端填充零,然后移动结果。如果需要,则不需要,因为移位会填充最初的msb。
struct.unpack('<i','\0'+ bytes)[0] >> 8
Python的struct
模块可让您通过控制字节顺序将字节解释为不同类型的数据结构。
如果从文件中读取单个三字节数字,则可以这样转换:
struct.unpack('<I', bytes + '\0')
该模块似乎不支持24位字,因此'\0'
-填充。
编辑:带符号的数字比较棘手。您可以复制高位,并将高位设置为零,因为它移到了4个字节的最高位(最后一个\xff
拥有它)。:
struct.unpack('<i', bytes + ('\0' if bytes[2] < '\x80' else '\xff'))
或者,对于python3(bytes
是保留字,检查字节数组的字节给出int
):
struct.unpack('<i', chunk + ('\0' if chunk[2] < 128 else '\xff'))
您的24位整数是带符号的还是无符号的? Bigendian或littleendian?
struct.unpack('<I', bytes + '\x00')[0] # unsigned littleendian
struct.unpack('>I', '\x00' + bytes)[0] # unsigned bigendian
Signed稍微复杂一点……获得上面的unsigned值,然后执行此操作:
signed = unsigned if not (unsigned & 0x800000) else unsigned - 0x1000000
如果您不介意使用外部库,那么我的bitstring模块在这里可能会有所帮助。
from bitstring import ConstBitStream
s = ConstBitStream(filename='some_file')
a = s.read('uintle:24')
这将读取前24位,并将其解释为无符号的Little-endian整数。将读取的s.pos
设置为24(流中的位位置)后,您便可以读取更多内容。例如,如果您想获取下一个10个有符号整数的列表,则可以使用
l = s.readlist('10*intle:24')
或者,如果您愿意,可以只使用切片和属性,而不必为读取而烦恼:
a = s[0:24].uintle
如果文件中已有3字节的数据,另一种选择就是创建和解释:
a = ConstBitStream(bytes=b'abc').uintle
有点晚,但是在这种情况下,这可能会有用。它以OP更新后的答案为基础,但将其集成到一个函数中,该函数从24位整数的打包文件中读取整个值列表。它主要是用struct来完成的,所以我认为它应该相当快。
def int24_to_int(self, input_data):
bytelen = len(input_data)
frames = bytelen/3
triads = struct.Struct('3s' * frames)
int4byte = struct.Struct('<i')
result = [int4byte.unpack('\0' + i)[0] >> 8 for i in triads.unpack(input_data)]
return result
[在Python 3中,我更喜欢使用int.from_bytes()
将3字节表示形式转换为32位整数。无需填充。
int.from_bytes()
或只是
value = int.from_bytes(input_data[0:3],'big',signed=True)
如果您的数组只有3个字节,并且默认为表示形式。