【问题标题】:mapping bytes produces int but single element bytes object is required映射字节产生 int 但需要单个元素字节对象
【发布时间】:2017-11-15 12:34:45
【问题描述】:

使用以下 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。因此,如果我手动遍历字节对象,我可以使用 [x:x+1] 而不是 [x] 访问元素。

我现在的问题是,是否有办法让 map 产生长度为 1 的字节对象,以便 unpack 函数得到它所期望的。

我发现这行得通

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

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

【问题讨论】:

    标签: python python-3.x lambda


    【解决方案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 生成器中:

    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]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-03
      • 2019-07-10
      • 1970-01-01
      相关资源
      最近更新 更多