Convertir int a cadena binaria en Python

8 minutos de lectura

Avatar de usuario de Nate
Nate

¿Cómo convierto un número entero en una cadena binaria en Python?

37   →   '100101'

  • Para la toma opuesta, para un algoritmo de procesamiento de cadenas puro, vea esto.

    – Copiar y Pegar

    15 de marzo de 2020 a las 17:05

Avatar de usuario de John Fouhy
Juan Fouhy

si estas buscando bin() como equivalente a hex()se agregó en python 2.6.

Ejemplo:

>>> bin(10)
'0b1010'

  • Tenga en cuenta también que es más rápido de hacer str(bin(i))[2:] (0.369s para 1000000ops) que "{0:b}".format(i) (0.721s para 1000000ops)

    – mVChr

    30 de octubre de 2013 a las 7:55

  • @mVChr si alguien está convirtiendo números en una representación binaria ASCII, realmente espero que la velocidad no importe.

    – Nick T.

    5 de febrero de 2014 a las 5:04

  • @mVChr: str.format() es la herramienta equivocada de todos modos, usaría format(i, 'b') en cambio. Sin embargo, tenga en cuenta que eso también le brinda opciones de relleno y alineación; format(i, '016b') para dar formato a un número binario de 16 bits con relleno cero. Para hacer lo mismo con bin() tendrías que agregar un str.zfill() llamar: bin(i)[2:].zfill(16) (no es necesario llamar str()!). format()legibilidad y flexibilidad (el formato dinámico es mucho más difícil con bin()) son excelentes compensaciones, no optimice el rendimiento a menos que tenga que hacerlo, hasta entonces optimice la capacidad de mantenimiento.

    – Martijn Pieters

    10 de diciembre de 2015 a las 10:28


  • Que hace [2:] ¿significar?

    – cero_cool

    18 de agosto de 2017 a las 20:43

  • Por supuesto, con python 3.6+ ahora puedes usar f"{37:b}".

    – Lucas Davis

    6 de noviembre de 2017 a las 6:48

  • Algunos buenos consejos en esta respuesta. Lástima que el código sea innecesariamente lento. Usted propone un algoritmo O (N ^ 2) donde funcionaría un O (N). La parte problemática está en el s = "1" + s y s = "0" + s líneas. Cada uno hace una copia innecesaria de s. Debe invertir la cadena justo antes de devolverla.

    – Andreas Magnuson

    9 de enero de 2020 a las 11:31

  • @Andreas, lo que yo propuesto era para usar '{0:b}'.format(42), el método lento fue simplemente un ejemplo de cómo hacerlo de forma genérica, que puede o no ser O (n ^ 2) según el idioma real utilizado. Solo se parece a Python, ya que Python es un lenguaje de pseudocódigo ideal, así que lo cambiaré para que quede claro.

    – pax diablo

    9 de enero de 2020 a las 13:25

  • En realidad sería un lenguaje bastante esotérico donde s = "1" + s no era O(N) cuando s es un tipo de cadena. ¿Quizás un idioma donde todas las cadenas se almacenan al revés o cada carácter es un nodo en una lista vinculada? Para cualquier lenguaje típico, una cadena es básicamente una matriz de caracteres. En ese caso, anteponer una cadena requiere que se haga una copia, ¿de qué otra manera vas a poner el carácter antes de los otros caracteres?

    – Andreas Magnuson

    9 de enero de 2020 a las 13:28


  • Puedo imaginar fácilmente un tipo de cadena que consta de un bloque de memoria donde la cadena está justificada a la derecha dentro de ese bloque y un desplazamiento de su carácter inicial. Para prefijar un carácter, simplemente reduciría el desplazamiento y almacenaría el carácter allí. Si, eso haría ser esotérico, pero tiene poco sentido para mí discutir sobre posibles problemas del mundo real con un poco de pseudocódigo, especialmente ya que no es probable que tenga más de unas pocas docenas de bits/iteraciones. Incluso el tipo de burbuja tan difamado es adecuado si el tamaño de sus datos es pequeño 🙂 En cualquier caso, agregaré una nota sobre la eficiencia.

    – pax diablo

    9 de enero de 2020 a las 15:11


  • Claro, si la eficiencia es importante, probablemente no elija Python para empezar. Aún así, en mi experiencia, sucede con bastante frecuencia que el código que se escribió ingenuamente usando un algoritmo O (N²) y se probó con un conjunto de datos pequeño se usa rápidamente con un conjunto de datos mucho más grande porque “parece funcionar”. Entonces, de repente, tiene un código que tarda horas en ejecutarse y, cuando se soluciona, puede tardar solo unos segundos. Los algoritmos O(N²) son insidiosos porque parecen funcionar durante un tiempo, pero cuando los datos se escalan no lo hacen y, para entonces, el tipo que los escribió se ha dado por vencido y nadie sabe por qué las cosas tardan una eternidad.

    – Andreas Magnuson

    9 de enero de 2020 a las 18:30

Avatar de usuario de Martin Thoma
Martín Tomas

Si desea una representación textual sin el prefijo 0b, puede usar esto:

get_bin = lambda x: format(x, 'b')

print(get_bin(3))
>>> '11'

print(get_bin(-3))
>>> '-11'

Cuando quieras una representación de n bits:

get_bin = lambda x, n: format(x, 'b').zfill(n)
>>> get_bin(12, 32)
'00000000000000000000000000001100'
>>> get_bin(-12, 32)
'-00000000000000000000000000001100'

Alternativamente, si prefiere tener una función:

def get_bin(x, n=0):
    """
    Get the binary representation of x.

    Parameters
    ----------
    x : int
    n : int
        Minimum number of digits. If x needs less digits in binary, the rest
        is filled with zeros.

    Returns
    -------
    str
    """
    return format(x, 'b').zfill(n)

  • O simplemente usa format(integer, 'b'). bin() es una herramienta de depuración, dirigida específicamente a producir el Sintaxis literal de enteros binarios de Python, format() está destinado a producir formatos específicos.

    – Martijn Pieters

    10 de diciembre de 2015 a las 10:21


  • @MartijnPieters Muchas gracias por mencionarlo. He ajustado mi solución. Como sabes eso bin() Qué es una herramienta de depuración destinada a producir la sintaxis literal de enteros binarios de Python? No pude encontrar eso en la documentación.

    – Martín Tomas

    10 dic 2015 a las 10:36

  • De la documentación: El resultado es una expresión de Python válida. Su objetivo es producir una expresión de Python, no producir representaciones de usuario final. Lo mismo se aplica a oct() y hex().

    – Martijn Pieters

    10 de diciembre de 2015 a las 10:37

  • Más alternativas: Si vas a hacer el ancho dinámico, en vez de str.zfill() podrías usar str.format() o format() con un segundo argumento dinámico: '{0:0{1}b}'.format(x, n) o format(b, '0{}b'.format(n)).

    – Martijn Pieters

    10 de diciembre de 2015 a las 10:41

  • @MartijnPieters ¡Guau, muchas gracias por este aporte! No sabía que esto era posible con el formato. Sin embargo, creo que mi respuesta actual con zfill es más fácil de leer y entender que el segundo argumento dinámico, así que lo mantendré.

    – Martín Tomas

    10 dic 2015 a las 10:45

Me sorprende que no se mencione una buena manera de lograr esto usando cadenas de formato que son compatibles con Python 3.6 y superior. TLDR:

>>> number = 1
>>> f'0b{number:08b}'
'0b00000001'

historia más larga

Esta es la funcionalidad de las cadenas de formato disponibles en Python 3.6:

>>> x, y, z = 1, 2, 3
>>> f'{x} {y} {2*z}'
'1 2 6'

También puede solicitar binarios:

>>> f'{z:b}'
'11'

Especifique el ancho:

>>> f'{z:8b}'
'      11'

Solicitud de relleno cero:

f'{z:08b}'
'00000011'

Y agregue un prefijo común para indicar un número binario:

>>> f'0b{z:08b}'
'0b00000011'

También puede dejar que Python agregue el prefijo por usted, pero no me gusta tanto como la versión anterior porque debe tener en cuenta el ancho del prefijo:

>>> f'{z:#010b}'
'0b00000011'

Más información está disponible en la documentación oficial en Literales de cadena con formato y Minilenguaje de especificación de formato.

  • O simplemente usa format(integer, 'b'). bin() es una herramienta de depuración, dirigida específicamente a producir el Sintaxis literal de enteros binarios de Python, format() está destinado a producir formatos específicos.

    – Martijn Pieters

    10 de diciembre de 2015 a las 10:21


  • @MartijnPieters Muchas gracias por mencionarlo. He ajustado mi solución. Como sabes eso bin() Qué es una herramienta de depuración destinada a producir la sintaxis literal de enteros binarios de Python? No pude encontrar eso en la documentación.

    – Martín Tomas

    10 dic 2015 a las 10:36

  • De la documentación: El resultado es una expresión de Python válida. Su objetivo es producir una expresión de Python, no producir representaciones de usuario final. Lo mismo se aplica a oct() y hex().

    – Martijn Pieters

    10 de diciembre de 2015 a las 10:37

  • Más alternativas: Si vas a hacer el ancho dinámico, en vez de str.zfill() podrías usar str.format() o format() con un segundo argumento dinámico: '{0:0{1}b}'.format(x, n) o format(b, '0{}b'.format(n)).

    – Martijn Pieters

    10 de diciembre de 2015 a las 10:41

  • @MartijnPieters ¡Guau, muchas gracias por este aporte! No sabía que esto era posible con el formato. Sin embargo, creo que mi respuesta actual con zfill es más fácil de leer y entender que el segundo argumento dinámico, así que lo mantendré.

    – Martín Tomas

    10 dic 2015 a las 10:45

avatar de usuario de kctong529
kctong529

Como una referencia:

def toBinary(n):
    return ''.join(str(1 & int(n) >> i) for i in range(64)[::-1])

Esta función puede convertir un entero positivo tan grande como 18446744073709551615representado como cadena '1111111111111111111111111111111111111111111111111111111111111111'.

Se puede modificar para servir a un número entero mucho más grande, aunque puede que no sea tan útil como "{0:b}".format() o bin().

  • @GarethDavidson, ¿qué versión es esta? Tener esto declarado explícitamente podría ser de mayor utilidad en el futuro al buscarlo en Google.

    – Lobo

    11 de abril de 2019 a las 10:56


  • Creo que era la versión 2.7. Dudo que funcione en 3.x

    – Gareth Davidson

    11 de abril de 2019 a las 22:24

¿Ha sido útil esta solución?