Convierta a binario y mantenga ceros a la izquierda en Python


154

Estoy tratando de convertir un entero a binario usando la función bin () en Python. Sin embargo, siempre elimina los ceros iniciales, que realmente necesito, de modo que el resultado sea siempre de 8 bits:

Ejemplo:

bin(1) -> 0b1

# What I would like:
bin(1) -> 0b00000001

¿Hay alguna forma de hacer esto?


Ver también: ¿ Python int a binario? , especialmente mi respuesta con la representación de n bits. No es exactamente lo mismo, pero llegué a esta pregunta buscando mi respuesta ...
— Martin Thoma

Respuestas:


219

Usa la format()función :

>>> format(14, '#010b')
'0b00001110'

La format()función simplemente formatea la entrada siguiendo el mini idioma de Especificación de formato . La #hace que el formato incluye el 0bprefijo, y el 010tamaño formatea la salida para caber en 10 caracteres de ancho, con 0material de relleno; 2 caracteres para el 0bprefijo, los otros 8 para los dígitos binarios.

Esta es la opción más compacta y directa.

Si coloca el resultado en una cadena más grande, use un literal de cadena con formato (3.6+) o use str.format()y coloque el segundo argumento para la format()función después de los dos puntos del marcador de posición {:..}:

>>> value = 14
>>> f'The produced output, in binary, is: {value:#010b}'
'The produced output, in binary, is: 0b00001110'
>>> 'The produced output, in binary, is: {:#010b}'.format(value)
'The produced output, in binary, is: 0b00001110'

De hecho, incluso para formatear un solo valor (sin poner el resultado en una cadena más grande), usar un literal de cadena formateado es más rápido que usar format():

>>> import timeit
>>> timeit.timeit("f_(v, '#010b')", "v = 14; f_ = format")  # use a local for performance
0.40298633499332936
>>> timeit.timeit("f'{v:#010b}'", "v = 14")
0.2850222919951193

Pero lo usaría solo si el rendimiento en un circuito cerrado es importante, ya que format(...)comunica mejor la intención.

Si no desea el 0bprefijo, simplemente suelte #y ajuste la longitud del campo:

>>> format(14, '08b')
'00001110'

3
Exactamente lo que estaba buscando, este formato es realmente útil para mí. Empecé a aprender la manipulación de bits y busqué en Google el formato de bits para números en Python. Encontró esto. Gracias.
— kratostoical

Funciona bien Sin embargo, puede volverse un poco voluminoso. format(192,'08b')+'.'+format(0,'08b')+'.'+format(2,'08b')+'.'+format(33,'08b') 11000000.00000000.00000010.00100001
— voces

@ tjt263: Es por eso que explícitamente afirmo que si está colocando el resultado en una cadena más grande, use un literal de cadena con formato (3.6+) o use str.format()y ponga el segundo argumento para la función format () después de los dos puntos del marcador de posición {:..}:
— Martijn Pieters

1
@ tjt263: por ejemplo, uso f"{192:08b}.{0:08b}.{2:08b}.{33:08b}".
— Martijn Pieters

Muy agradable. Nunca hubiera sabido que a eso te referías solo con una explicación. Pero ahora que he visto tu ejemplo, probablemente nunca lo olvidaré. Salud.
— voces

115
>>> '{:08b}'.format(1)
'00000001'

Ver: Especificación de formato Mini-idioma


Nota para Python 2.6 o anterior, no puede omitir el identificador de argumento posicional antes :, así que use

>>> '{0:08b}'.format(1)
'00000001'      

3
No hay necesidad de usar str.format()aquí cuando format()lo hará. Te falta el 0bprefijo.
— Martijn Pieters

2
@MartijnPieters, str.formates más flexible que format()porque te permitirá hacer múltiples variables a la vez. Sigo olvidando que la formatfunción incluso existe. Es cierto que es perfectamente adecuado en este caso.
— Mark Ransom

1
@MarkRansom: Exactamente, cuando solo usa str.format()un solo {}elemento, ningún otro texto, no usa plantillas de cadenas, está formateando un valor . En ese caso solo úsalo format(). :-)
— Martijn Pieters

30

estoy usando

bin(1)[2:].zfill(8)

imprimirá

'00000001'

9

Puede usar el mini idioma de formato de cadena:

def binary(num, pre='0b', length=8, spacer=0):
    return '{0}{{:{1}>{2}}}'.format(pre, spacer, length).format(bin(num)[2:])

Manifestación:

print binary(1)

Salida:

'0b00000001'

EDITAR: basado en la idea de @Martijn Pieters

def binary(num, length=8):
    return format(num, '#0{}b'.format(length + 2))

2
Se puede usar el mismo lenguaje de formato para incluir el prefijo. Uso #. También existe format(), lo que le ahorra tener que hacer una plantilla de cadena completa.
— Martijn Pieters

2

Cuando se usa Python >= 3.6, la forma más limpia es usar cadenas f con formato de cadena :

>>> var = 23
>>> f"{var:#010b}"
'0b00010111'

Explicación:

  • var la variable a formatear
  • : todo después de esto es el especificador de formato
  • #usa la forma alternativa (agrega el 0bprefijo)
  • 0 almohadilla con ceros
  • 10pad a una longitud total de 10 (esto incluye los 2 caracteres para 0b)
  • b usar representación binaria para el número

No, no es el más limpio, no a menos que haga más con la cadena que un solo marcador de posición . De lo contrario, format(var, "#010b")comunica la intención mucho mejor. Sin embargo, es la opción más rápida. Pero eso ya lo sabes, porque ya cubro todo lo que publicaste en mi respuesta.
— Martijn Pieters

1

A veces solo quieres un revestimiento simple:

binary = ''.join(['{0:08b}'.format(ord(x)) for x in input])

Python 3


1
Tenga en cuenta que [ ]no debería ser necesario: join()acepta una expresión generadora. ''.join('{0:08b}'.format(ord(x)) for x in input)
— Christoph Burschka

@ChristophBurschka nota que debido a que str.join()necesita hacer dos pases, una entrada del generador se convierte primero en una lista antes de unirse. Esto tiene un costo en el rendimiento y es realmente mejor pasar una comprensión de la lista en lugar de una expresión generadora. Es uno si son excepciones a la regla.
— Martijn Pieters

-1

Puedes usar algo como esto

("{:0%db}"%length).format(num)

2
Al menos use el bloque de código para su fragmento de código. Y si realmente quiere que sea una buena respuesta, también agregue algunos comentarios sobre por qué esta solución está resolviendo la pregunta OP.
— β.εηοιτ.βε

No necesita usar un estilo de formato de cadena diferente solo para agregar un ancho variable. Simplemente agregue otro marcador de posición:"{:0{l}b}".format(num, l=length)
— Martijn Pieters

-1

puede usar el método de cadena rjust de la sintaxis de python: string.rjust (length, fillchar) fillchar es opcional

y para tu pregunta puedes escribir así

'0b'+ '1'.rjust(8,'0)

entonces será '0b00000001'


Hay un error de sintaxis. Pero lo que es más importante, no responde a la pregunta, que se trata de convertir una inta su representación binaria textual; Ni siquiera empiezas con un int.
— Thierry Lathuille

-3

Puedes usar zfill:

print str(1).zfill(2) 
print str(10).zfill(2) 
print str(100).zfill(2)

huellas dactilares:

01
10
100

Me gusta esta solución, ya que ayuda no solo al generar el número, sino también cuando necesita asignarlo a una variable ... por ejemplo, x = str (datetime.date.today (). Month) .zfill (2) will devuelve x como '02' para el mes de febrero.


1
El problema con zfill es que trata la cadena binaria como una cadena y agrega los ceros antes del indicador binario 'b' ... por ejemplo, bin(14) da '' 0b1110 '' y bin(14).zfill(8) da '' 000b1110 '' no '' 0b00001110 '', que es lo que se desea
— Shaun
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.