Python将二进制文件列表转换为字符串
我有一个1和0的列表-->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]]
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]很棒的解决方案!我花了一些时间