将列表中的元素转换为二进制

7
假设我有一个列表:
lst = [0, 1, 0, 0]

如何使python将这个列表解释为二进制数0100,以便 2*(0100) 可以给出01000

我能想到的唯一方法是先创建一个将"二进制"元素转换为对应整数(基于10)的函数,然后使用bin()函数。

是否有更好的方法?


int已经是二进制表示法了。为了在屏幕上打印,字面量及其打印表示会转换为十进制数。但你可以对它们进行位运算,因为底层表示法是二进制的。如果你想使用二进制字面量,请在你的解释器中尝试0b1000。现在试试12 * 0b1000。只有当你想要显示一个二进制表示时,你才需要显式地使用bin() - juanpa.arrivillaga
8个回答

5
您可以像这样使用位运算符:位运算符
>>> lst = [0, 1, 0, 0]
 >>> bin(int(''.join(map(str, lst)), 2) << 1)
'0b1000'

4

被接受的答案,即连接字符串,并不是最快的。

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() 的速度是其他方法的双倍!


4
这不是花哨的一行代码,而是简单快速的。
lst = [0,1,1,0]

num = 0
for b in lst:
    num = 2 * num + b
print(num) # 6

1
因为我目前有一个项目,需要将黑白图像转换为字节数组并通过TCP发送,所以我在寻找“尽可能快”的解决方案。
于是我从这里找到了一些解决方案,加入了一些我自己想到的内容,并进行了一些速度测试。
我认为分享这些可能会有帮助...
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

1

稍微不同的理解方法(我希望对某些人有所帮助)

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]) 

0
你可以使用以下代码来连接列表元素:
x=[0, 1, 0, 0]
b=''.join(map(str,x))
print(b)

输出:

C:\python\prog>python trying.py

0100

0

在Jupyter中:

lst = [4,5,7,1,2]
bin(int(''.join(map(str, lst)))<<1)

输出:'0b10110010100100000'

在Python Shell中:

>>> lst =[4,5,7,1,2]
>>> bin(int(''.join(map(str, lst)))<<1)

输出:'0b10110010100100000'


很遗憾,答案不符合问题的条件:列表必须填充表示二进制值的“0”和“1”。 - Sergey Shubin

-2

你可以尝试:

l = [0, 0, 1, 0]
num = int(''.join(str(x) for x in l), base=2)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接