【问题标题】:Convert base-2 binary number string to int将 base-2 二进制数字符串转换为 int
【发布时间】:2012-02-14 05:47:12
【问题描述】:

我只想将 base-2 二进制数字字符串转换为 int,如下所示:

>>> '11111111'.fromBinaryToInt()
255

有没有办法在 Python 中做到这一点?

【问题讨论】:

  • 虽然这并不重要,但二进制字符串通常意味着包含实际二进制数据的字符串(一个字节包含两个十六进制数字,即“\x00”是一个空字节)。
  • 顺便提一下:反之亦然,例如 '{0:08b}'.format(65)(或 f'{65:08b}')。

标签: python


【解决方案1】:

您使用内置的int() 函数,并将输入数字的基数传递给它,即2 用于二进制数:

>>> int('11111111', 2)
255

这是Python 2Python 3 的文档。

【讨论】:

  • 谢谢,正是我想要的。
  • 如果有人在寻找相反的东西:bin(255) -> '0b11111111'。有关更多详细信息,请参阅this answer
  • 需要注意的是,这只适用于无符号二进制整数。对于有符号整数,转换选项是一团糟。
  • 如何在 python 3 中做到这一点?
  • 请注意,在交互式 REPL 会话中(如 >>> 提示所建议的那样),您根本不需要使用 print。 OP的假设示例没有。所以它在 Python 2 和 3 中确实应该是相同的。
【解决方案2】:

另一种方法是使用bitstring 模块:

>>> from bitstring import BitArray
>>> b = BitArray(bin='11111111')
>>> b.uint
255

注意无符号整数与有符号整数不同:

>>> b.int
-1

bitstring 模块不是必需的,但它有许多高效的方法可以将输入转换为位和从位转换为其他形式,以及对其进行操作。

【讨论】:

    【解决方案3】:

    将 int 与 base 一起使用是正确的方法。在我发现 int 也需要基础之前,我曾经这样做过。它基本上是对将二进制转换为十进制的原始方法的列表理解的简化(例如 110 = 2**0 * 0 + 2 ** 1 * 1 + 2 ** 2 * 1)

    add = lambda x,y : x + y
    reduce(add, [int(x) * 2 ** y for x, y in zip(list(binstr), range(len(binstr) - 1, -1, -1))])
    

    【讨论】:

    • 可以提供add = lambda x, y: x + y而不是定义int.__add__来减少。例如。 reduce(int.__add__, ...)
    【解决方案4】:

    只需在python交互界面中输入0b11111111

    >>> 0b11111111
        255
    

    【讨论】:

      【解决方案5】:

      如果你想知道幕后发生的事情,那么就去吧。

      class Binary():
          def __init__(self, binNumber):
              self._binNumber = binNumber
              self._binNumber = self._binNumber[::-1]
              self._binNumber = list(self._binNumber)
              self._x = [1]
              self._count = 1
              self._change = 2
              self._amount = 0
              print(self._ToNumber(self._binNumber))
          def _ToNumber(self, number):
              self._number = number
              for i in range (1, len (self._number)):
                  self._total = self._count * self._change
                  self._count = self._total
                  self._x.append(self._count)
              self._deep = zip(self._number, self._x)
              for self._k, self._v in self._deep:
                  if self._k == '1':
                      self._amount += self._v
              return self._amount
      
      mo = Binary('101111110')
      

      【讨论】:

        【解决方案6】:

        递归 Python 实现:

        def int2bin(n):
            return int2bin(n >> 1) + [n & 1] if n > 1 else [1] 
        

        【讨论】:

          【解决方案7】:

          如果您使用的是 python3.6 或更高版本,您可以使用 f-string 来执行 转换:

          二进制转十进制:

          >>> print(f'{0b1011010:#0}')
          90
          
          >>> bin_2_decimal = int(f'{0b1011010:#0}')
          >>> bin_2_decimal
          90
          

          二进制转八进制等

          >>> f'{0b1011010:#o}'
          '0o132'  # octal
          
          >>> f'{0b1011010:#x}'
          '0x5a'   # hexadecimal
          
          >>> f'{0b1011010:#0}'
          '90'     # decimal
          

          注意用冒号隔开的2条信息。

          这样,你可以通过改变冒号[:]的右边来将{binary, octal, hexadecimal, decimal}转换成{binary, octal, hexadecimal, decimal}

          :#b -> converts to binary
          :#o -> converts to octal
          :#x -> converts to hexadecimal 
          :#0 -> converts to decimal as above example
          

          尝试将冒号左侧更改为八进制/十六进制/十进制。

          【讨论】:

            【解决方案8】:

            对于大型矩阵(10**5 行及以上),最好使用矢量化 matmult。一次通过所有行和列。它非常快。这里的python没有循环。我最初设计它是为了将 MovieLens 中 10 个不同类型列的许多二进制列(例如 0/1)转换为每个示例行的单个整数。

            def BitsToIntAFast(bits):
              m,n = bits.shape
              a = 2**np.arange(n)[::-1]  # -1 reverses array of powers of 2 of same length as bits
              return bits @ a
            

            【讨论】:

              【解决方案9】:

              在基本python3中来回记录:

              a = 10
              bin(a)
              # '0b1010'
              
              int(bin(a), 2)
              # 10
              eval(bin(a))
              # 10
              

              【讨论】:

                【解决方案10】:

                这是上述任何答案中都没有提到的另一种简洁的方法:

                >>> eval('0b' + '11111111')
                255
                

                诚然,它可能不是很快,如果字符串来自您无法控制的可能是恶意的东西(例如用户输入),这是一个非常非常糟糕的主意,但为了完整起见,它确实有效。

                【讨论】:

                • 这对于硬编码的常量可能没问题,但是使用eval 被认为是不好的做法有多种原因,尤其是当您尝试解析用户输入时。看这个帖子,例如:stackoverflow.com/questions/1832940/…
                • 我喜欢这个答案,很有创意
                猜你喜欢
                • 2021-07-17
                • 2013-01-30
                • 1970-01-01
                • 2014-11-28
                • 2016-05-07
                • 1970-01-01
                • 2016-07-13
                • 2021-02-24
                相关资源
                最近更新 更多