Python将二进制文件列表转换为字符串

Python将二进制文件列表转换为字符串,python,python-3.x,string,list,binary,Python,Python 3.x,String,List,Binary,我有一个1和0的列表-->output=[1,1,0,0,0,0,1,0,1,1,1,1,0,1,0] 我想把1和0的列表转换成一个字符串,“litlle-endian”中的每8位代表“latin1”中的一个字母 到目前为止,我有这个代码(如下),它工作得很好,但我认为它相当慢,似乎减慢了我的脚本 for i in range(0,len(output),8): x=output[i:i+8] l="".join([str(j) for j in x[::-1]]

我有一个1和0的列表-->
output=[1,1,0,0,0,0,1,0,1,1,1,1,0,1,0]

我想把1和0的列表转换成一个字符串,“litlle-endian”中的每8位代表“latin1”中的一个字母

到目前为止,我有这个代码(如下),它工作得很好,但我认为它相当慢,似乎减慢了我的脚本

for i in range(0,len(output),8):
        x=output[i:i+8]
        l="".join([str(j) for j in x[::-1]])
        out_str += chr(int(("0b"+l),base=2))

你有更快的想法吗?

检查这是否更快:

tmp_list = []
for i in range(0,len(output),8):
    byte_value = 0
    for digit in output[i:i+8:-1]:
        byte_value = (byte_value<<1) + digit
    tmp_list.append(chr(byte_value))
out_str = ''.join(tmp_list)
tmp_列表=[]
对于范围内的i(0,len(输出),8):
字节值=0
对于输出中的数字[i:i+8:-1]:

字节值=(字节值检查是否更快:

tmp_list = []
for i in range(0,len(output),8):
    byte_value = 0
    for digit in output[i:i+8:-1]:
        byte_value = (byte_value<<1) + digit
    tmp_list.append(chr(byte_value))
out_str = ''.join(tmp_list)
tmp_列表=[]
对于范围内的i(0,len(输出),8):
字节值=0
对于输出中的数字[i:i+8:-1]:

byte_value=(byte_value使用
sum
enumerate
应该更快,因为它们是内置的。让我们在同一台机器上计算您和我的时间

在一个循环中运行100000次,并使用
time python3 tmp.py
进行测试(
user
值。对于
sys
时间量,它们都徘徊在0.012s左右,因此它对结果只有百分比影响。)

您的:0m1.624s
我的速度快了50%:0m1.063s,用这个

output=[1,1,0,0,0,0,1,0,1,1,1,0,1,1,0]
对于范围(0,len(output),8)中i的[输出[i:i+8]中的项):

out_str+=chr(sum)(x使用
sum
enumerate
应该更快,因为它们是内置的。让我们在同一台机器上对您和我的进行计时

在一个循环中运行100000次,并使用
time python3 tmp.py
进行测试(
user
值。对于
sys
时间量,它们都徘徊在0.012s左右,因此它对结果只有百分比影响。)

您的:0m1.624s
我的速度快了50%:0m1.063s,用这个

output=[1,1,0,0,0,0,1,0,1,1,1,0,1,1,0]
对于范围(0,len(output),8)中i的[输出[i:i+8]中的项):

out_str+=chr(sum(x这里有一个更快的解决方案,使用元组字典来查找256个可能的字符:

bits = [1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0]

chars = { tuple(map(int,f"{n:08b}"[::-1])):chr(n) for n in range(0,256) }

def toChars(bits):
    return "".join(chars[tuple(bits[i:i+8])] for i in range(0,len(bits),8) )
大约比原始解决方案快3倍

[EDIT]和一个使用字节和zip的更快版本:

chars = { tuple(map(int,f"{n:08b}")):n for n in range(256) }
def toChars(bits):
    return bytes(chars[b] for b in zip(*(bits[7-i::8] for i in range(8)))).decode()
大约比前一个快2倍(在长列表中)

[EDIT2]最后一个的一些解释

  • 列表中的
    b
    将是一个8位的元组
  • chars[b]
    将返回与8位相对应的整数
  • bytes(…).decode()
    基于每个值的chr(n)将整数列表转换为字符串
  • zip(*…8位迭代器…)
    解压并行运行的8个跨距范围的位,每个位从不同的起点开始
解包zip的策略是以8的步骤遍历位。例如,如果我们遍历8个并行范围,我们将得到以下结果:

 bits[7::8] -> [ 0, 0, ... ]  zip returns: (0,1,0,0,0,1,1)
 bits[6::8] -> [ 1, 1, ... ]               (0,1,1,0,1,1,1)
 bits[5::8] -> [ 0, 1, ... ]               ...
 bits[4::8] -> [ 0, 0, ... ]
 bits[3::8] -> [ 0, 1, ... ]
 bits[2::8] -> [ 0, 1, ... ]
 bits[1::8] -> [ 1, 1, ... ]
 bits[0::8] -> [ 1, 1, ... ] 

zip函数将在每次迭代中获取其中的一列,并将其作为位元组返回。

下面是一个更快的解决方案,使用元组字典来查找256个可能的字符:

bits = [1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0]

chars = { tuple(map(int,f"{n:08b}"[::-1])):chr(n) for n in range(0,256) }

def toChars(bits):
    return "".join(chars[tuple(bits[i:i+8])] for i in range(0,len(bits),8) )
大约比原始解决方案快3倍

[EDIT]和一个使用字节和zip的更快版本:

chars = { tuple(map(int,f"{n:08b}")):n for n in range(256) }
def toChars(bits):
    return bytes(chars[b] for b in zip(*(bits[7-i::8] for i in range(8)))).decode()
大约比前一个快2倍(在长列表中)

[EDIT2]最后一个的一些解释

  • 列表中的
    b
    将是一个8位的元组
  • chars[b]
    将返回与8位相对应的整数
  • bytes(…).decode()
    基于每个值的chr(n)将整数列表转换为字符串
  • zip(*…8位迭代器…)
    解压并行运行的8个跨距范围的位,每个位从不同的起点开始
解包zip的策略是以8的步骤遍历位。例如,如果我们遍历8个并行范围,我们将得到以下结果:

 bits[7::8] -> [ 0, 0, ... ]  zip returns: (0,1,0,0,0,1,1)
 bits[6::8] -> [ 1, 1, ... ]               (0,1,1,0,1,1,1)
 bits[5::8] -> [ 0, 1, ... ]               ...
 bits[4::8] -> [ 0, 0, ... ]
 bits[3::8] -> [ 0, 1, ... ]
 bits[2::8] -> [ 0, 1, ... ]
 bits[1::8] -> [ 1, 1, ... ]
 bits[0::8] -> [ 1, 1, ... ] 

zip函数将在每次迭代中获取其中的一列,并将其作为位元组返回。

我对所有有效解决方案的执行时间进行了一些测量。请参见下面的代码中的结果。代码从最慢到最快进行排序。Fatest是其中的一个。我在一个相当大的列表中测试了这些代码,得到了200个字符串000个字符

即使对于如此大的列表,执行时间仍然相当快,对于我的原始解决方案也是如此。我的程序中肯定有其他地方存在问题…:-)

谢谢你们的代码

import time
start_time = time.time()
bits = [1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0] * 100000
    ### tested code ###
print("Execution time: ", time.time() - start_time, "seconds")


### former solution --> 0.59 seconds
out_str = ""
for i in range(0,len(bits),8):
    x=bits[i:i+8]
    l="".join([str(j) for j in x[::-1]])
    out_str += chr(int(("0b"+l),base=2))


### enumerate and result.append --> 0.48 seconds
result = []
c = 0
for i,v in enumerate(bits):
    i = i % 8
    c = c | v << i
    if i == 7:
        result.append(chr(c))
        c = 0
out_str = ''.join(result)


### sum and enumerate --> 0.45 seconds
out_str = ""
for item in [bits[i:i + 8] for i in range(0, len(bits), 8)]:
    out_str += chr(sum(x<<i for i,x in enumerate(item)))


### map and chars dictionary --> 0.10 seconds
chars = { tuple(map(int,f"{n:08b}"[::-1])):chr(n) for n in range(0,256) }
def toChars(bits):
    return "".join(chars[tuple(bits[i:i+8])] for i in range(0,len(bits),8) )


### bytes and zip --> 0.06 seconds
chars = { tuple(map(int,f"{n:08b}")):n for n in range(256) }
def toChars(bits):
    return bytes(chars[b] for b in zip(*(bits[7-i::8] for i in range(8)))).decode()

我对所有有效解决方案的执行时间进行了一些测量。请参见下面代码中的结果。代码按从最慢到最快的顺序进行排序。Fatest是中的一个。我在一个相当大的列表上测试了代码,得到了一个200000个字符的字符串

即使对于如此大的列表,执行时间仍然相当快,对于我的原始解决方案也是如此。我的程序中肯定有其他地方存在问题…:-)

谢谢你们的代码

import time
start_time = time.time()
bits = [1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0] * 100000
    ### tested code ###
print("Execution time: ", time.time() - start_time, "seconds")


### former solution --> 0.59 seconds
out_str = ""
for i in range(0,len(bits),8):
    x=bits[i:i+8]
    l="".join([str(j) for j in x[::-1]])
    out_str += chr(int(("0b"+l),base=2))


### enumerate and result.append --> 0.48 seconds
result = []
c = 0
for i,v in enumerate(bits):
    i = i % 8
    c = c | v << i
    if i == 7:
        result.append(chr(c))
        c = 0
out_str = ''.join(result)


### sum and enumerate --> 0.45 seconds
out_str = ""
for item in [bits[i:i + 8] for i in range(0, len(bits), 8)]:
    out_str += chr(sum(x<<i for i,x in enumerate(item)))


### map and chars dictionary --> 0.10 seconds
chars = { tuple(map(int,f"{n:08b}"[::-1])):chr(n) for n in range(0,256) }
def toChars(bits):
    return "".join(chars[tuple(bits[i:i+8])] for i in range(0,len(bits),8) )


### bytes and zip --> 0.06 seconds
chars = { tuple(map(int,f"{n:08b}")):n for n in range(256) }
def toChars(bits):
    return bytes(chars[b] for b in zip(*(bits[7-i::8] for i in range(8)))).decode()

第二个循环不应该是:
输出中的数字[i+8:i:-1]
?但无论如何它似乎不起作用。对于这个循环,结果应该是
“Co”
。第二个循环不应该是:
输出中的数字[i+8:i:-1]
?但无论如何它似乎不起作用。结果应该是
“Co”
对于这一个。您使用此例程的目的是什么?您是否在数千个不同值的列表上重复执行此操作?我必须运行您的示例100000次(!)要获得超过亚秒的计时。如果输出是文本,我将解码200000个字符–一本书中大约1000页。您使用此例程的目的是什么?您是否在数千个不同值的列表上重复执行此操作?我必须运行您的示例100000次(!)如果输出是文本,我会解码200000个字符——一本书大约有1000页……因为它只有8个值,[x……因为它只有8个值,[x]很棒的解决方案!我花了一些时间