6 python optimization bit-manipulation python-3.x
我正在尝试在 Python 3.x 中将位字符串转换为字节字符串。在每个字节中,位从高位到低位填充。如有必要,最后一个字节用零填充。位串最初存储为布尔值或整数(0 或 1)的“集合”,我想返回 0-255 范围内整数的“集合”。通过集合,我的意思是一个列表或一个类似的对象,而不是一个字符串:例如,下面的函数返回一个生成器。
到目前为止,我能得到的最快的是以下内容:
def bitsToBytes(a):
s = i = 0
for x in a:
s += s + x
i += 1
if i == 8:
yield s
s = i = 0
if i > 0:
yield s << (8 - i)
Run Code Online (Sandbox Code Playgroud)
我尝试了几种替代方法:使用枚举,构建列表而不是生成器,通过“(s << 1) | x”而不是总和来计算 s,一切似乎都慢了一点。由于此解决方案也是我发现的最短和最简单的解决方案之一,因此我对此感到非常满意。
但是,我想知道是否有更快的解决方案。特别是,是否有一个库例程可以更快地完成工作,最好是在标准库中?
示例输入/输出
[] -> []
[1] -> [128]
[1,1] -> [192]
[1,0,0,0,0,0,0,0,1] -> [128,128]
Run Code Online (Sandbox Code Playgroud)
在这里,我展示了带有列表的示例。发电机应该没问题。但是,字符串不会,然后有必要在类似列表的数据和字符串之间来回转换。
在 8-er 块中消耗位并忽略异常的最简单策略:
def getbytes(bits):
done = False
while not done:
byte = 0
for _ in range(0, 8):
try:
bit = next(bits)
except StopIteration:
bit = 0
done = True
byte = (byte << 1) | bit
yield byte
Run Code Online (Sandbox Code Playgroud)
用法:
lst = [1,0,0,0,0,0,0,0,1]
for b in getbytes(iter(lst)):
print b
Run Code Online (Sandbox Code Playgroud)
getbytes
是一个生成器并接受一个生成器,也就是说,它可以很好地处理大型且可能无限的流。