假设我有一个列表:
lst = [0, 1, 0, 0]
如何使python将这个列表解释为二进制数0100,以便 2*(0100)
可以给出01000
?
我能想到的唯一方法是先创建一个将"二进制"元素转换为对应整数(基于10)的函数,然后使用bin()函数。
是否有更好的方法?
lst = [0, 1, 0, 0]
如何使python将这个列表解释为二进制数0100,以便 2*(0100)
可以给出01000
?
我能想到的唯一方法是先创建一个将"二进制"元素转换为对应整数(基于10)的函数,然后使用bin()函数。
是否有更好的方法?
被接受的答案,即连接字符串,并不是最快的。
import random
lst = [int(i < 50) for i in random.choices(range(100), k=100)]
def join_chars(digits):
return int(''.join(str(i) for i in digits), 2)
%timeit join_chars(lst)
13.1 µs ± 450 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
def sum_digits(digits):
return sum(c << i for i, c in enumerate(digits))
%timeit sum_digits(lst)
5.99 µs ± 65.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
因此,通过按位操作实现 sum_digits()
的速度是其他方法的双倍!
lst = [0,1,1,0]
num = 0
for b in lst:
num = 2 * num + b
print(num) # 6
import timeit
BIN_LIST = [1, 0, 1, 0, 1, 0, 1, 0]
TIMEIT_ITERATIONS = 10000
def f_01(l):
return bin(int(''.join(map(str, l)), 2) << 1)
def f_02(l):
num = 0
for b in l:
num = 2 * num + b
return num
def f_03(l):
return int(''.join(str(i) for i in l), 2)
def f_04(l):
return sum(c << i for i, c in enumerate(l))
def f_05(l):
return bin(int(''.join(map(str, l)))<<1)
"""
From here on it's just stuff I tried out for myself
"""
def f_06(l):
res = 0
for i, v in enumerate(l[::-1]):
res += v << i
return res
def f_07(l):
res = 0
for i, v in enumerate(l):
res += v << 7 - i
return res
def f_08(l):
"""
Well, why not
"""
return int(f"{l[0]}{l[1]}{l[2]}{l[3]}{l[4]}{l[5]}{l[6]}{l[7]}", base=2)
def f_09(l):
"""
bear with me
"""
return int("{}{}{}{}{}{}{}{}".format(*l), base=2)
def f_10(l, i=7, r=0):
"""
let's try a little recursion
"""
if i >= 0:
return f_10(l, i-1, r + (l[i] << 7 - i))
else:
return r
"""
Last try with C code
"""
from cffi import FFI
ffi = FFI()
ffi.set_source("c_make_bin",
"""
int f_11(unsigned char l[8])
{
int res = 0 ;
for (int i=0; i<8; i+=1)
{
res = 2 * res + l[i] ;
}
return res ;
}
""")
ffi.cdef("""int f_11(unsigned char[8]) ;""")
ffi.compile()
from c_make_bin import lib
p = ffi.new("unsigned char[]", BIN_LIST)
"""
And well, look to the results -> C Code is .. and stays the fastest
"""
t_01 = timeit.Timer(lambda: f_01(BIN_LIST))
t_02 = timeit.Timer(lambda: f_02(BIN_LIST))
t_03 = timeit.Timer(lambda: f_03(BIN_LIST))
t_04 = timeit.Timer(lambda: f_04(BIN_LIST))
t_05 = timeit.Timer(lambda: f_05(BIN_LIST))
t_06 = timeit.Timer(lambda: f_06(BIN_LIST))
t_07 = timeit.Timer(lambda: f_07(BIN_LIST))
t_08 = timeit.Timer(lambda: f_08(BIN_LIST))
t_09 = timeit.Timer(lambda: f_09(BIN_LIST))
t_10 = timeit.Timer(lambda: f_10(BIN_LIST))
t_11 = timeit.Timer(lambda: lib.f_11(p))
result_01 = t_01.timeit(TIMEIT_ITERATIONS)
result_02 = t_02.timeit(TIMEIT_ITERATIONS)
result_03 = t_03.timeit(TIMEIT_ITERATIONS)
result_04 = t_04.timeit(TIMEIT_ITERATIONS)
result_05 = t_05.timeit(TIMEIT_ITERATIONS)
result_06 = t_06.timeit(TIMEIT_ITERATIONS)
result_07 = t_07.timeit(TIMEIT_ITERATIONS)
result_08 = t_08.timeit(TIMEIT_ITERATIONS)
result_09 = t_09.timeit(TIMEIT_ITERATIONS)
result_10 = t_10.timeit(TIMEIT_ITERATIONS)
result_11 = t_11.timeit(TIMEIT_ITERATIONS)
print("\n--- Test Results ---\n\n")
print("Function 01:", round(result_01, 5), "s", " --- join, map")
print("Function 02:", round(result_02, 5), "s", " --- simple for")
print("Function 03:", round(result_03, 5), "s", " --- join, tuple comprehension")
print("Function 04:", round(result_04, 5), "s", " --- shift, enumerate")
print("Function 05:", round(result_05, 5), "s", " --- join, map [2]")
print("Function 06:", round(result_06, 5), "s", " --- shift, reverse, enumerate in for")
print("Function 07:", round(result_07, 5), "s", " --- shift, enumerate in for")
print("Function 08:", round(result_08, 5), "s", " --- fstring")
print("Function 09:", round(result_09, 5), "s", " --- "".format")
print("Function 10:", round(result_10, 5), "s", " --- recursive")
print("Function 11:", round(result_11, 5), "s", " --- compiled C code")
终端输出:
--- Test Results ---
Function 01: 0.02623 s --- join, map
Function 02: 0.00718 s --- simple for
Function 03: 0.03302 s --- join, tuple comprehension
Function 04: 0.01773 s --- shift, enumerate
Function 05: 0.02497 s --- join, map [2]
Function 06: 0.0141 s --- shift, reverse, enumerate in for
Function 07: 0.01427 s --- shift, enumerate in for
Function 08: 0.01479 s --- fstring
Function 09: 0.01344 s --- .format
Function 10: 0.02424 s --- recursive
Function 11: 0.0047 s --- compiled C code
稍微不同的理解方法(我希望对某些人有所帮助)
arr =[192, 168, 0, 1]
arr_s = [bin(i)[2:].zfill(8) for i in ar]
num = int(''.join(arr_s), 2)
相同,但顺序相反(也适用于lambda的单行代码)
arr = [24, 85, 0]
num = int(''.join( [bin(i)[2:].zfill(8) for i in arr[::-1]] ), 2)
using bit-wise and reduce:
reduce ((lambda x,y: (x<<8)|y), arr[::-1])
x=[0, 1, 0, 0]
b=''.join(map(str,x))
print(b)
输出:
C:\python\prog>python trying.py
0100
lst = [4,5,7,1,2]
bin(int(''.join(map(str, lst)))<<1)
输出:'0b10110010100100000'
>>> lst =[4,5,7,1,2]
>>> bin(int(''.join(map(str, lst)))<<1)
输出:'0b10110010100100000'
你可以尝试:
l = [0, 0, 1, 0]
num = int(''.join(str(x) for x in l), base=2)
int
已经是二进制表示法了。为了在屏幕上打印,字面量及其打印表示会转换为十进制数。但你可以对它们进行位运算,因为底层表示法是二进制的。如果你想使用二进制字面量,请在你的解释器中尝试0b1000
。现在试试12 * 0b1000。只有当你想要显示一个二进制表示时,你才需要显式地使用bin()
。 - juanpa.arrivillaga