我试图在Python 3.x中将位字符串转换为字节字符串。在每个字节中,位从高位到低位填充。如有必要,最后一个字节用零填充。位串最初存储为"集合" booleans或整数(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)
我尝试了几种方法:使用枚举,建立列表而不是生成器,通过&#34;(s&lt;&lt; 1)|来计算s。 X&#34;而不是总和,一切似乎都有点慢。由于这个解决方案也是我发现的最简单和最简单的解决方案之一,我对它很满意。
但是,我想知道是否有更快的解决方案。特别是,是否有一个库例程可以更快地完成工作,最好是在标准库中?
输入/输出示例
[] -> []
[1] -> [128]
[1,1] -> [192]
[1,0,0,0,0,0,0,0,1] -> [128,128]
这里我用列表显示示例。发电机没问题。但是,字符串不会,然后有必要将类似列表的数据之间的转换和foth转换为字符串。
答案 0 :(得分:3)
消耗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
用法:
lst = [1,0,0,0,0,0,0,0,1]
for b in getbytes(iter(lst)):
print b
getbytes
是一个生成器并接受一个生成器,也就是说,它适用于大型且可能无限的流。
答案 1 :(得分:2)
步骤1:添加缓冲区零
步骤2:反转位,因为您的字节顺序被反转
第3步:连接成一个字符串
步骤4:一次将8位保存到数组
第5步:
第6步:获利
def bitsToBytes(a):
a = [0] * (8 - len(a) % 8) + a # adding in extra 0 values to make a multiple of 8 bits
s = ''.join(str(x) for x in a)[::-1] # reverses and joins all bits
returnInts = []
for i in range(0,len(s),8):
returnInts.append(int(s[i:i+8],2)) # goes 8 bits at a time to save as ints
return returnInts
答案 2 :(得分:2)
使用itertools
' grouper()` recipe:
from functools import reduce
from itertools import zip_longest
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)
bytes = [reduce(lambda byte, bit: byte << 1 | bit, eight_bits)
for eight_bits in grouper(bits, 8, fillvalue=0)]
[] -> []
[1] -> [128]
[1, 1] -> [192]
[1, 0, 0, 0, 0, 0, 0, 0, 1] -> [128, 128]
如果输入是一个字符串,那么专门的解决方案可能会更快:
>>> bits = '100000001'
>>> padded_bits = bits + '0' * (8 - len(bits) % 8)
>>> padded_bits
'1000000010000000'
>>> list(int(padded_bits, 2).to_bytes(len(padded_bits) // 8, 'big'))
[128, 128]
如果len(bits) % 8 == 0
,则最后一个字节为零。