【问题标题】:Is there a more pythonic way to convert a list of booleans to an integer?是否有更 Pythonic 的方式将布尔值列表转换为整数?
【发布时间】:2020-03-06 23:09:47
【问题描述】:

我觉得问这个问题很愚蠢,但我的记忆让我没有更好的选择。脑海中浮现的两种方法:

第一:

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 几乎是 Python 的笨拙,而 f2 显然太丑了,因为我在多种数据类型之间跳转。也许是我的年龄......?

【问题讨论】:

  • 有什么理由需要索引的总和吗?为什么你不能只做sum(list_of_bools) 在这种情况下等于2
  • @PyPingu 他们没有计算索引的总和。他们将布尔值解释为二进制数,其中第一个元素是个,第二个是二位,第三个是四位,依此类推。
  • 我知道它实际上不仅仅是简单地对索引求和,但问题是“将布尔列表转换为整数”所以我想知道是否有某种原因可以直接求和不是所需要的。 FWIW 如果这是预期的结果,我真的不认为 f1 是一个糟糕的解决方案。

标签: python python-3.x binary


【解决方案1】:

使用左移比提高幂稍快(至少在我的机器上)。使用按位运算可以鼓励代码读者从二进制数据的角度进行思考。

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

【讨论】:

    【解决方案2】:

    只是为了对比,如果你在写 python 就像你在写 c 之类的东西一样,你会这样做。

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

    【讨论】:

      【解决方案3】:

      在算术运算(也是 lambda 函数)中使用布尔值非常符合 Python 风格:

      lst = [True, False, True]
      
      func = lambda x: sum(2 ** num * i for num, i in enumerate(x))
      
      print(func(lst))
      # 5
      

      【讨论】:

        【解决方案4】:

        这是我想出的另一种 hacky 方式:

        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)
        

        【讨论】:

          【解决方案5】:

          它的解决方案更加严格,但非常计算效率很高

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

          【讨论】:

            猜你喜欢
            • 2011-03-11
            • 1970-01-01
            • 1970-01-01
            • 2011-04-06
            • 2016-07-17
            • 2013-12-03
            • 2011-02-07
            • 2016-04-14
            • 1970-01-01
            相关资源
            最近更新 更多