还有一种将Python列表转换为整数的更Python化的方法吗?

时间:2019-11-11 09:09:41

标签: python python-3.x binary

我不得不问这个问题很傻,但是我的记忆却使我无法找到更好的选择。我想到两个方法:

第一:

def f1(v):
    return sum(2**i for i,va in enumerate(v) if va)

>>> f1([True, False, True])
5

第二:

def f2(v):
    return int('0b' + "".join(str(int(va)) for va in v),2)

>>> f2([True, False, True])
5

我觉得f1几乎笨拙到不能成为pythonic,而f2显然太难看了,因为我在多个数据类型之间切换。也许是我的年龄...?

5 个答案:

答案 0 :(得分:4)

使用左移要比加电稍快(至少在我的机器上)。使用按位运算会鼓励代码阅读者从二进制数据角度进行思考。

>>> sum(v << i for i, v in enumerate([True, False, True]))
5

答案 1 :(得分:1)

在算术运算(也就是lambda函数)中使用布尔值是非常Python化的:

lst = [True, False, True]

func = lambda x: sum(2 ** num * i for num, i in enumerate(x))

print(func(lst))
# 5

答案 2 :(得分:1)

为了对比,如果您正在编写python,就像编写c之类的东西,那么您可以采用这种方式。

def f(l):
  output = 0
  for i in range(len(l)):
    output |= l[i] << i
  return output

答案 3 :(得分:0)

这是我想出的另一种方法:

def f1(v):
    return int(''.join(str(int(b)) for b in v), 2)

示例:

>>> def f1(v):
...     return int(''.join(str(int(b)) for b in v), 2)
...
>>> f1([True, False, True])
5
>>>

使用map的另一个相同示例(在我看来更可读):

def f1(v):
    return int(''.join(map(str, map(int, v))), 2)

答案 4 :(得分:0)

它的解决方案更为严格,但其在计算上非常有效

>>> import numpy as np

>>> predefined_bytes = 2**(np.arange(32))
>>> predefined_bytes
array([         1,          2,          4,          8,         16,
               32,         64,        128,        256,        512,
             1024,       2048,       4096,       8192,      16384,
            32768,      65536,     131072,     262144,     524288,
          1048576,    2097152,    4194304,    8388608,   16777216,
         33554432,   67108864,  134217728,  268435456,  536870912,
       1073741824, 2147483648])


def binary2decimal(bits,predefined_bytes):
    bits = np.array(bits)
    return np.sum(bits*predefined_bytes[:bits.shape[0]])

>>> binary2decimal([1,1,1,1,1,1,1,1],predefined_bytes)
255