如何将Python元组(字节数组)的一部分转换为整数?

8

我正在尝试使用Python与设备通信。我得到了一个包含存储信息的字节元组。如何将数据转换为正确的值:

response = (0, 0, 117, 143, 6)

前4个值是32位整数,告诉我已经使用了多少字节,最后一个值是使用的百分比。

我可以通过response [0]访问元组,但不知道如何将前4个值转换为所需的整数。

6个回答

13

请问,

num = (response[0] << 24) + (response[1] << 16) + (response[2] << 8) + response[3]

满足您的需求吗?
帮助

2
当我看到以上的答案需要导入模块,使用循环和推导式来处理这么简单的问题时,我真的开始感到困惑了……这个答案实际上是如此(应该是)在任何地方都应该被执行,并且在速度和简洁性方面没有什么可以超越它了…… - Tom

12

请查看在Python中将字节转换为浮点数

您可能需要使用struct模块,例如:

import struct

response = (0, 0, 117, 143, 6)
struct.unpack(">I", ''.join([chr(x) for x in response[:-1]]))

假设有一个无符号整数。可能有更好的方法将其转换为解包,使用列表理解和join只是我想到的第一件事情。
编辑:关于字节顺序,请参见ΤΖΩΤΖΙΟΥ在此答案中的评论。
编辑#2:如果您不介意同时使用数组模块,这里是一种替代方法,它消除了对列表理解的需要。感谢@JimB指出unpack也可以作用于数组。
import struct
from array import array

response = (0, 0, 117, 143, 6)
bytes = array('B', response[:-1])
struct.unpack('>I', bytes)

1
我建议使用大端格式">I",即0x0000758f(30095₁₀)作为随机字节数的计数更有可能,而不是0x8f750000(2406809600₁₀)。 - tzot

4

好的,您没有指定字节序或整数是否为有符号的,也许使用struct模块更快,但以下是一种可能更简单的方法:

b = (8, 1, 0, 0)
sum(b[i] << (i * 8) for i in range(4))

仅供参考,这适用于小端模式,并且可能可以稍微改进为“sum(b [i] <<(i * 8)for i in range(len(b)))”,以允许可变大小的输入,或使用“sum(response [i] <<(i * 8)for i in range(len(response)-1))”来进行操作。 - Caltor
@Ad__ 我喜欢这个解决方案,因为它可能比 struct.unpack 更快,并且不像那种方法需要导入一个模块。不过,你能提供一个可以处理大端序的版本吗? - Caltor

4
你可以使用数组模块。
import struct
from array import array
response = (0, 0, 117, 143, 6)
a = array('B', response[:4])
struct.unpack('>I', a)

(30095L,)

我也尝试了这种方法,但最终决定使用列表推导式和join()代替,以避免导入另一个模块,并且由于两者都不是特别清晰。 - Jay
我忘记了结构体可以打包数组[已修复的答案],我认为这个版本比列表推导式略好。 - JimB
不错,我不知道它可以这样做,文档中漏掉了这一点。我会将其作为备选项添加到我的答案中。 - Jay

2

这看起来需要使用reduce函数!

基本上你需要做的是,每次按位移动一个字节,然后将序列中的下一个字节加上(加法)。

a = (0, 0, 117, 143, 6)
reduce(lambda x, y: (x<<8) + y, a)
7704326

-1 阅读问题。有五个字节。OP说前四个是32位整数。最后一个是百分比(6%)。 - John Machin
@John: 我认为这只是一个小错误,只需将第二行中的a更改为a[:4],代码就可以按照OP所需的方式正常工作(至少如果是大端)。没有必要直接点踩。 - Elmar Zander
@Kristian,能否提供一个适用于小端的版本? - Caltor
1
考虑到John的评论,@Caltor:reduce(lambda x, y: (x<<8) + y, a[:4][::-1]) - Jon Ander Ortiz Durántez

0

使用map函数怎么样:

a = (0, 0, 117, 143, 6)
b = []
map(b.append, a)

另外,我不知道这是否符合您的要求:

response = (0, 0, 117, 143, 6)
response[0:4]

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