如何将大字节对象转换为 32 位整数值列表?

ysa*_*sap 2 python type-conversion python-3.x

我有一个bytes对象,其长度(以字节为单位)是 4 的倍数。我想将其转换为32 位整数值n的列表。n/4

什么是有效的方法来做到这一点?

例如,转换xy

x = b'\x01\x02\x03\x04\xef\xbe\xad\xde'
y = [0x04030201, 0xdeadbeef]
Run Code Online (Sandbox Code Playgroud)

更新1:找出这段代码。有没有更简单的方法(一种内衬解决方案)?

x = b'\x01\x02\x03\x04\xef\xbe\xad\xde'
ls = [x[n:(n+4)] for n in range(0, len(x), 4)]
y = []
for xx in [int.from_bytes(xx, 'little') for xx in ls]:
    y.append(xx)
Run Code Online (Sandbox Code Playgroud)

更新 2:我意识到我可以合并两个循环:

x = b'\x01\x02\x03\x04\xef\xbe\xad\xde'
y = [int.from_bytes(x[n:(n+4)], 'little') for n in range(0, len(x), 4)]
Run Code Online (Sandbox Code Playgroud)

这是否像它所得到的那么优雅?

che*_*ner 5

您可以使用该struct模块。

>>> x = b'\x01\x02\x03\x04\xef\xbe\xad\xde'
>>> from struct import unpack
>>> unpack(f'<{len(x)//4}I', x)
(67305985, 3735928559)
Run Code Online (Sandbox Code Playgroud)

(需要计算要解包的整数的确切数量,而不是能够说“给我尽可能多的整数x”,这有点烦人。)


jua*_*aga 5

可能最简单的事情就是使用 an array.array,您需要无符号整数,因此您需要"I"作为类型代码:

>>> import array
>>> x = b'\x01\x02\x03\x04\xef\xbe\xad\xde'
>>> arr = array.array('I', x)
>>> arr
array('I', [67305985, 3735928559])
Run Code Online (Sandbox Code Playgroud)

请注意,当使用 初始化时,它将使用本机字节顺序bytes,但如果需要,您可以对其进行字节交换:

>>> arr.byteswap()
>>> arr
array('I', [16909060, 4022250974])
>>> arr.byteswap()
>>> arr
array('I', [67305985, 3735928559])
Run Code Online (Sandbox Code Playgroud)

如果项目需要numpy,您还可以轻松使用 numpy,在那里您可以指定 中的字节顺序dtype,在本例中,无符号整数为u,然后直接为其指定字节大小:

>>> np.frombuffer(x, dtype='<u4')
array([  67305985, 3735928559], dtype=uint32)
Run Code Online (Sandbox Code Playgroud)

如果您确实需要一个list对象(array.array对象几乎是完美的替代品,np.ndarray对象具有不太兼容的接口),您可以简单地转换:

list(array.array('I', x))
Run Code Online (Sandbox Code Playgroud)

或者对于numpy

np.frombuffer(x, dtype='<u4').tolist()
Run Code Online (Sandbox Code Playgroud)

注意,list(np.array())应该避免,因为它给你一个listnumpy.uint32 对象(基本上是装箱的原始值,你说你想要实际的 pythonint对象)。