搜索更优雅的方式将字节转换为位列表

时间:2016-02-02 10:03:43

标签: python list function byte bit

我目前正在使用这个小函数将一个字节转换为整数位列表,因为我需要迭代一个字节的单个位。

def byteToBitList(byte):
    return [int(bit) for bit in "{0:08b}".format(byte)]

但我认为它不是很优雅。有一个更好的方法吗?可能没有使用字符串?

4 个答案:

答案 0 :(得分:2)

您始终可以使用bitwise operations,它可以与标准整数对象一起使用。只需将您的第一位移位,并收集最右侧的位值。例如:

>>> byte = 0xFC
>>> list_size = 8
>>> [(byte >> i) & 1 for i in range(list_size)][::-1] # reverse this array, since left-most bits are evaluated first.
[1, 1, 1, 1, 1, 1, 0, 0]

使用IPython进行计时:1000000 loops, best of 3: 1.54 µs per loop

甚至可以在不反转数组的情况下生成此列表:

>>> byte = 0xFC
>>> list_size = 8
>>> [(byte & (1 << (list_size - 1 - k))) >> (list_size - 1 - k) for k in range(list_size)]
[1, 1, 1, 1, 1, 1, 0, 0]

使用IPython进行计时:100000 loops, best of 3: 2.3 µs per loop。显然,逆转列表比使用两班倒更快!

此外,this Stack Overflow thread包含一个非常相似的问题。

答案 1 :(得分:2)

如果要避免字符串操作,可以使用二进制操作,即将<<>>与逻辑和&结合使用。

>>> def byteToBitList(byte):
    return [(byte & (1 << k)) >> k for k in range(8)]

>>> byteToBitList(0xfc)
[0, 0, 1, 1, 1, 1, 1, 1]

答案 2 :(得分:1)

您可以使用以下解决方案,速度要快一些:

byte = 0xfc

In [206]: list(map(int, bin(byte)[2:].zfill(8)))
Out[206]: [1, 1, 1, 1, 1, 1, 0, 0]

<强>时序

In [209]: %timeit byteToBitList(byte)
100000 loops, best of 3: 5.69 us per loop

In [211]: %timeit list(map(int, bin(byte)[2:].zfill(8)))
100000 loops, best of 3: 4.27 us per loop

答案 3 :(得分:1)

您可以将bin()str.zfill()进行一些修剪,将整数转换为二进制表示形式:

def byteToBitList(byte):
    return [int(bit) for bit in bin(byte)[2:].zfill(8)]

这假设byte确实是值为0-255的无符号整数。任何更大的和结果列表将超过8位,虽然结果是正确的,只是没有填充。