Converter string de número binário base-2 em int

306

Eu simplesmente gostaria de converter uma string de número binário base-2 em um int, algo como isto:

>>> '11111111'.fromBinaryToInt()
255

Existe uma maneira de fazer isso em Python?

Naftuli Kay
fonte
3
Embora isso realmente não importe, uma string binária normalmente significa uma string que contém dados binários reais (um byte contém dois dígitos hexadecimais, ou seja, "\ x00" é um byte nulo).
trevorKirkby

Respostas:

563

Você usa a intfunção embutida e passa a ela a base do número de entrada, ou seja, 2para um número binário:

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

Aqui está a documentação para python2 e python3 .

descontrair
fonte
61
Caso alguém esteja procurando o oposto: bin(255)-> '0b11111111'. Veja esta resposta para detalhes adicionais.
Akseli Palén 13/03/2013
7
Note-se que isso funciona apenas para números inteiros binários não assinados. Para números inteiros assinados, as opções de conversão são uma bagunça.
Fake Name
2
Como fazer isso em python 3?
Saras Arya
2
@SarasArya É muito parecido! :) Eu atualizei, veja acima.
descontraia
1
E observe que, em uma sessão REPL interativa (como sugerido pelo >>>prompt), você não precisa usar printnada. O exemplo hipotético do OP não. Então, ele realmente deve ser idêntica em Python 2 e 3.
John Y
37

Basta digitar 0b11111111 na interface interativa python:

>>> 0b11111111
    255
lengxuehx
fonte
28

Outra maneira de fazer isso é usando o bitstringmódulo:

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

Observe que o número inteiro não assinado é diferente do número inteiro assinado:

>>> b.int
-1

O bitstringmódulo não é um requisito, mas possui muitos métodos de desempenho para transformar a entrada em e de bits em outras formas, além de manipulá-los.

Alex Reynolds
fonte
8

Usar int com base é o caminho certo a seguir. Eu costumava fazer isso antes de encontrar o int também se baseia. É basicamente uma redução aplicada em uma lista de compreensão da maneira primitiva de converter binário em decimal (por exemplo, 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))])
Saurabh Hirani
fonte
4
Em vez de definir add = lambda x, y: x + y, int.__add__pode ser fornecido para reduzir. Por exemploreduce(int.__add__, ...)
Jordan Jambazov 28/08
4

Se você quer saber o que está acontecendo nos bastidores, então aqui está.

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')
Mohammad Mahjoub
fonte
3

Uma implementação Python recursiva:

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

Se você estiver usando python3.6 ou posterior, poderá usar a string f para fazer a conversão:

Binário para decimal:

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

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

binário para hexa octal e etc.

>>> f'{0b1011010:#o}'
'0o132'  # octal

>>> f'{0b1011010:#x}'
'0x5a'   # hexadecimal

>>> f'{0b1011010:#0}'
'90'     # decimal

Preste atenção a 2 informações separadas por dois pontos.

Dessa maneira, você pode converter entre {binário, octal, hexadecimal, decimal} em {binário, octal, hexadecimal, decimal} alterando o lado direito dos dois pontos [:]

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

Tente alterar o lado esquerdo do cólon para ter octal / hexadecimal / decimal.

Robert Ranjan
fonte
0

Para matrizes grandes (10 ** 5 linhas e acima), é melhor usar um matmult vetorizado. Passe em todas as linhas e colunas de uma só vez. É extremamente rápido. Não há loop em python aqui. Eu o projetei originalmente para converter muitas colunas binárias como 0/1 em 10 colunas de gênero diferentes no MovieLens em um único número inteiro para cada linha de exemplo.

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
Geoffrey Anderson
fonte