映射字节产生int但需要单个元素字节对象

时间:2017-11-15 12:34:46

标签: python python-3.x lambda

使用以下lambda

映射字节类型
unpack = lambda val: struct.unpack("!b", val)[0]

list(map(unpack, b'\xb1\xbb\n\x0f'))

给出错误

TypeError: a bytes-like object is required, not 'int'

documentation

  

由于字节对象是整数序列(类似于元组),对于字节对象b,b [0]将是整数,而b [0:1]将是长度为1的字节对象。与文本字符串形成对比,其中索引和切片都将生成一个长度为1)的字符串

解释了传递int的原因。因此,如果我手动循环遍历bytes对象,我可以使用[x:x+1]而不是[x]来访问元素。

现在我的问题是,如果有一种方法可以使map生成长度为1的字节对象,那么unpack函数就会得到它所期望的。

我发现这有效

unpack = lambda val: struct.unpack("!b", bytes(bytearray([val])))[0]

但对我来说这似乎是一个丑陋的解决方法。有没有更好,更简洁的方法呢?

1 个答案:

答案 0 :(得分:1)

我所知道的还没有更简洁的方法。 A proposition已经完成,但它仍然是草案。

尽管如此,你仍然有一些其他的选择,以使它看起来更友好。例如,一个产生字节的小生成器:

def iterbytes(b):
    for n in range(len(b)):
        yield b[n:n+1]   

或类似但可能更慢:

def iterbytes(b):
    for i in b:
        yield bytes([i])

然后在这个iterbytes生成器中包装bytes对象:

list(map(unpack, iterbytes(b'\xb1\xbb\n\x0f')))

由于你将map包裹在list中,即你在列表之后,我可能会理解而不是map

>>> b = b'\xb1\xbb\n\x0f' 
>>> [unpack(b[i:i+1]) for i in range(len(b))]
[-79, -69, 10, 15]