str.format()solo formatear un valor es exagerado. Ir directamente a la format()función : format(n, 'b'). No es necesario analizar el marcador de posición y asociarlo a un argumento, vaya directamente a la operación de formateo de valor en sí. Úselo solo str.format()si necesita colocar el resultado formateado en una cadena más larga (por ejemplo, úsela como plantilla).
Martijn Pieters
29
@mike: O use la especificación de formato. Agregue el número de dígitos con una 0cadena a la cadena de formato: format(10, '016b')formatos de 16 dígitos con ceros a la izquierda.
Martijn Pieters
En este caso, el 0en "{0:b}"se puede soltar no? Quiero decir, en el caso de que solo se esté formateando un número, es correcto ponerlo "{:b}", ¿no?
tomasyany
1
normalmente se usaría una representación de 4/8 / ... bit:"{:08b}".format(37)
Sparkler
2
f "{37: b}" en Python3.7 o posterior.
DA
471
Si está buscando bin()como equivalente a hex(), se agregó en python 2.6.
Tenga en cuenta también que es más rápido str(bin(i))[2:](0.369s para 1000000ops) que "{0:b}".format(i)(0.721s para 1000000ops)
mVChr
64
@mVChr si alguien está convirtiendo números en una representación binaria ASCII, realmente espero que la velocidad no importe.
Nick T
29
@mVChr: str.format()es la herramienta incorrecta de todos modos, en su format(i, 'b')lugar usaría . Tenga en cuenta que eso también le ofrece opciones de relleno y alineación; format(i, '016b')formatear a un número binario de 16 bits con relleno cero. Para hacer lo mismo con bin()usted, debe agregar una str.zfill()llamada: bin(i)[2:].zfill(16)(¡no es necesario llamar str()!). format()La legibilidad y flexibilidad (el formato dinámico es mucho más difícil bin()) son grandes compensaciones, no optimice el rendimiento a menos que sea necesario, hasta entonces optimice la capacidad de mantenimiento.
Martijn Pieters
¿Qué significa [2:]?
zero_cool
44
Por supuesto, con Python 3.6+ ahora puede usar f"{37:b}".
Luke Davis el
63
Python en realidad hace tener algo ya incorporado para esto, la capacidad de hacer operaciones como '{0:b}'.format(42), lo que le dará el patrón de bits (en una cadena) a 42, o 101010.
Para una filosofía más general, ningún idioma o biblioteca dará a su base de usuarios todo lo que desean. Si está trabajando en un entorno que no proporciona exactamente lo que necesita, debe recopilar fragmentos de código a medida que se desarrolla para asegurarse de que nunca tenga que escribir lo mismo dos veces. Como, por ejemplo, el pseudocódigo:
define intToBinString, receiving intVal:if intVal is equal to zero:return"0"
set strVal to ""while intVal is greater than zero:if intVal is odd:
prefix "1" to strValelse:
prefix "0" to strVal
divide intVal by two, rounding downreturn strVal
que construirá su cadena binaria basada en el valor decimal. Solo tenga en cuenta que es un poco de pseudocódigo genérico que puede no ser la forma más eficiente de hacerlo, sin embargo, con las iteraciones que parece proponer, no hará mucha diferencia. Realmente solo se entiende como una guía sobre cómo se podría hacer.
La idea general es usar código de (en orden de preferencia):
el idioma o las bibliotecas integradas.
bibliotecas de terceros con licencias adecuadas.
tu propia colección
algo nuevo que necesita escribir (y guardar en su propia colección para más adelante).
Algunos buenos consejos en esta respuesta. Lástima que el código sea innecesariamente lento. Propones un O (N ^ 2) algo donde haría un O (N). La parte problemática está en las líneas s = "1" + sy s = "0" + s. Cada uno hace una copia innecesaria de s. En su lugar, debe invertir la cadena justo antes de devolverla.
Andreas Magnusson
@Andreas, lo que propuse fue usar '{0:b}'.format(42), el método lento fue simplemente un ejemplo de cómo hacerlo genéricamente, que puede ser o no O (n ^ 2) dependiendo del lenguaje 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.
paxdiablo
En realidad, sería un lenguaje bastante esotérico donde s = "1" + sno era O (N) cuando ses 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, el prefijo de una cadena requiere que se haga una copia, ¿de qué otra manera va a poner el carácter antes que los otros caracteres?
Andreas Magnusson el
Puedo imaginar fácilmente un tipo de cadena que consiste en un bloque de memoria donde la cadena está justificada a la derecha dentro de ese bloque, y un desplazamiento a su carácter inicial. Para prefijar un carácter, simplemente reduciría el desplazamiento y almacenaría el carácter allí. Sí, eso sería esotérico, pero tiene poco sentido para mí discutir sobre posibles problemas del mundo real con un poco de pseudocódigo, especialmente porque no es probable que tenga más de unas pocas docenas de bits / iteraciones. Incluso el tipo de burbuja muy difamado es adecuado si el tamaño de sus datos es pequeño :-) En cualquier caso, agregaré una nota sobre la eficiencia.
paxdiablo
Claro, si la eficiencia es importante, probablemente no elegirías Python para empezar. Aún así, en mi experiencia, sucede con bastante frecuencia que el código que fue escrito ingenuamente usando un algoritmo O (N²) y probado con un pequeño conjunto de datos se usa rápidamente con un conjunto de datos mucho más grande porque "parece funcionar". Entonces, de repente, tiene un código que demora horas en ejecutarse y que cuando se soluciona puede demorar solo unos segundos. Los algos O (N²) son insidiosos porque parecen funcionar por un tiempo, pero cuando tus datos escalan, no lo hacen y para entonces el tipo que los escribió ha renunciado y nadie sabe por qué las cosas tardan para siempre.
Andreas Magnusson
41
Si desea una representación textual sin el prefijo 0b, puede usar esto:
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 usar format(integer, 'b'). bin()es una herramienta de depuración, específicamente dirigida a producir la sintaxis literal entera binaria de Python , format()está destinada a producir formatos específicos.
Martijn Pieters
1
@MartijnPieters Muchas gracias por mencionarlo. He ajustado mi solución. ¿Cómo sabe que bin()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.
Martin Thoma
2
De la documentación: El resultado es una expresión Python válida . Su objetivo es producir una expresión de Python, no generar representaciones de usuario final. Lo mismo se aplica a oct()y hex().
Martijn Pieters
44
Más alternativas: si va a hacer que el ancho sea dinámico, en lugar de str.zfill()podría 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
@MartijnPieters ¡Guau, muchas gracias por este aporte! No sabía que esto era posible con el formato. Sin embargo, creo que mi respuesta actual zfilles más fácil de leer y comprender que el segundo argumento dinámico, por lo que lo guardaré.
Martin Thoma
38
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 18446744073709551615, representado como una cadena '1111111111111111111111111111111111111111111111111111111111111111'.
Se puede modificar para servir un número entero mucho más grande, aunque puede no ser tan útil como "{0:b}".format()o bin().
eso devuelve '' para 0 sin embargo. ¿No sería la representación normal para 0 '0'?
dietbacon
si quieres ver ese 0 :), puedes reemplazarlo ''por '0', pero agregará un 0 inicial para cualquier número.
Aziz Alto
11
Resumen de alternativas:
n=42assert"-101010"== format(-n,'b')assert"-101010"=="{0:b}".format(-n)assert"-101010"==(lambda x: x >=0and str(bin(x))[2:]or"-"+ str(bin(x))[3:])(-n)assert"0b101010"== bin(n)assert"101010"== bin(n)[2:]# But this won't work for negative numbers.
str.format()solo formatear un valor es exagerado. Ir directamente a la format()función: format(n, 'b'). No es necesario analizar el marcador de posición y compararlo con un argumento de esa manera.
Martijn Pieters
10
Como las respuestas anteriores utilizan principalmente el formato (), aquí hay una implementación de f-string.
Usando numpy pack / unpackbits, son tus mejores amigos.
Examples-------->>> a = np.array([[2],[7],[23]], dtype=np.uint8)>>> a
array([[2],[7],[23]], dtype=uint8)>>> b = np.unpackbits(a, axis=1)>>> b
array([[0,0,0,0,0,0,1,0],[0,0,0,0,0,1,1,1],[0,0,0,1,0,1,1,1]], dtype=uint8)
La pregunta es sobre una representación de cadena . Aún así, ¡resultó ser justo lo que estaba buscando sin pasar primero por la cadena! :)
Tom Hale
El doco dice: elementos desempaqueta de una uint8matriz en una matriz de salida binaria de valor. Muy bueno para valores de hasta 255.
Tom Hale
5
Para aquellos de nosotros que necesitamos convertir enteros con signo (rango -2 ** (dígitos-1) a 2 ** (dígitos-1) -1) a cadenas binarias complementarias de 2, esto funciona:
La segunda versión definitivamente no es más rápida, ya que terminas con algo así como un algoritmo O (N ^ 2) en lugar de un O (N). He visto cosas como esta que matan una aplicación (en cuanto al rendimiento) porque el desarrollador pensó que hacer un pase adicional al final era más lento que hacer algunas cosas adicionales en el primer bucle. Una vez arreglado, el tiempo de funcionamiento disminuyó de días a segundos.
Aquí está el código que acabo de implementar. ¡Este no es un método, pero puede usarlo como una función lista para usar !
def inttobinary(number):if number ==0:return str(0)
result =""while(number !=0):
remainder = number%2
number = number/2
result += str(remainder)return result[::-1]# to invert the string
Aquí hay otra forma de usar las matemáticas regulares, sin bucles, solo recursividad. (El caso trivial 0 no devuelve nada).
def toBin(num):if num ==0:return""return toBin(num//2)+ str(num%2)print([(toBin(i))for i in range(10)])['','1','10','11','100','101','110','111','1000','1001']
Calculadora con todas las funciones necesarias para DEC, BIN, HEX: (hecho y probado con Python 3.5)
Puede cambiar los números de prueba de entrada y obtener los convertidos.
# CONVERTER: DEC / BIN / HEXdef dec2bin(d):# dec -> bin
b = bin(d)return b
def dec2hex(d):# dec -> hex
h = hex(d)return h
def bin2dec(b):# bin -> dec
bin_numb="{0:b}".format(b)
d = eval(bin_numb)return d,bin_numb
def bin2hex(b):# bin -> hex
h = hex(b)return h
def hex2dec(h):# hex -> dec
d = int(h)return d
def hex2bin(h):# hex -> bin
b = bin(h)return b
## TESTING NUMBERS
numb_dec =99
numb_bin =0b0111
numb_hex =0xFF## CALCULATIONS
res_dec2bin = dec2bin(numb_dec)
res_dec2hex = dec2hex(numb_dec)
res_bin2dec,bin_numb = bin2dec(numb_bin)
res_bin2hex = bin2hex(numb_bin)
res_hex2dec = hex2dec(numb_hex)
res_hex2bin = hex2bin(numb_hex)## PRINTINGprint('------- DECIMAL to BIN / HEX -------\n')print('decimal:',numb_dec,'\nbin: ',res_dec2bin,'\nhex: ',res_dec2hex,'\n')print('------- BINARY to DEC / HEX -------\n')print('binary: ',bin_numb,'\ndec: ',numb_bin,'\nhex: ',res_bin2hex,'\n')print('----- HEXADECIMAL to BIN / HEX -----\n')print('hexadec:',hex(numb_hex),'\nbin: ',res_hex2bin,'\ndec: ',res_hex2dec,'\n')
Respuestas:
El método de formato de cadena de Python puede tomar una especificación de formato.
Formato de documentación de especificaciones para Python 2
Formato de documentación de especificaciones para Python 3
fuente
str.format()
solo formatear un valor es exagerado. Ir directamente a laformat()
función :format(n, 'b')
. No es necesario analizar el marcador de posición y asociarlo a un argumento, vaya directamente a la operación de formateo de valor en sí. Úselo solostr.format()
si necesita colocar el resultado formateado en una cadena más larga (por ejemplo, úsela como plantilla).0
cadena a la cadena de formato:format(10, '016b')
formatos de 16 dígitos con ceros a la izquierda.0
en"{0:b}"
se puede soltar no? Quiero decir, en el caso de que solo se esté formateando un número, es correcto ponerlo"{:b}"
, ¿no?"{:08b}".format(37)
Si está buscando
bin()
como equivalente ahex()
, se agregó en python 2.6.Ejemplo:
fuente
str(bin(i))[2:]
(0.369s para 1000000ops) que"{0:b}".format(i)
(0.721s para 1000000ops)str.format()
es la herramienta incorrecta de todos modos, en suformat(i, 'b')
lugar usaría . Tenga en cuenta que eso también le ofrece opciones de relleno y alineación;format(i, '016b')
formatear a un número binario de 16 bits con relleno cero. Para hacer lo mismo conbin()
usted, debe agregar unastr.zfill()
llamada:bin(i)[2:].zfill(16)
(¡no es necesario llamarstr()
!).format()
La legibilidad y flexibilidad (el formato dinámico es mucho más difícilbin()
) son grandes compensaciones, no optimice el rendimiento a menos que sea necesario, hasta entonces optimice la capacidad de mantenimiento.f"{37:b}"
.Python en realidad hace tener algo ya incorporado para esto, la capacidad de hacer operaciones como
'{0:b}'.format(42)
, lo que le dará el patrón de bits (en una cadena) a42
, o101010
.Para una filosofía más general, ningún idioma o biblioteca dará a su base de usuarios todo lo que desean. Si está trabajando en un entorno que no proporciona exactamente lo que necesita, debe recopilar fragmentos de código a medida que se desarrolla para asegurarse de que nunca tenga que escribir lo mismo dos veces. Como, por ejemplo, el pseudocódigo:
que construirá su cadena binaria basada en el valor decimal. Solo tenga en cuenta que es un poco de pseudocódigo genérico que puede no ser la forma más eficiente de hacerlo, sin embargo, con las iteraciones que parece proponer, no hará mucha diferencia. Realmente solo se entiende como una guía sobre cómo se podría hacer.
La idea general es usar código de (en orden de preferencia):
fuente
s = "1" + s
ys = "0" + s
. Cada uno hace una copia innecesaria de s. En su lugar, debe invertir la cadena justo antes de devolverla.'{0:b}'.format(42)
, el método lento fue simplemente un ejemplo de cómo hacerlo genéricamente, que puede ser o no O (n ^ 2) dependiendo del lenguaje 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.s = "1" + s
no era O (N) cuandos
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, el prefijo de una cadena requiere que se haga una copia, ¿de qué otra manera va a poner el carácter antes que los otros caracteres?Si desea una representación textual sin el prefijo 0b, puede usar esto:
Cuando quieres una representación de n bits:
Alternativamente, si prefiere tener una función:
fuente
format(integer, 'b')
.bin()
es una herramienta de depuración, específicamente dirigida a producir la sintaxis literal entera binaria de Python ,format()
está destinada a producir formatos específicos.bin()
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.oct()
yhex()
.str.zfill()
podría usarstr.format()
oformat()
con un segundo argumento dinámico:'{0:0{1}b}'.format(x, n)
oformat(b, '0{}b'.format(n))
.zfill
es más fácil de leer y comprender que el segundo argumento dinámico, por lo que lo guardaré.Como una referencia:
Esta función puede convertir un entero positivo tan grande como
18446744073709551615
, representado como una cadena'1111111111111111111111111111111111111111111111111111111111111111'
.Se puede modificar para servir un número entero mucho más grande, aunque puede no ser tan útil como
"{0:b}".format()
obin()
.fuente
Una forma sencilla de hacerlo es usar el formato de cadena, consulte esta página .
Y si desea tener una longitud fija de la cadena binaria, puede usar esto:
Si se requiere el complemento a dos, entonces se puede usar la siguiente línea:
donde n es el ancho de la cadena binaria.
fuente
¡Esto es para Python 3 y mantiene los ceros a la izquierda!
fuente
one-liner con lambda :
prueba:
EDITAR :
pero entonces :(
en comparación con
fuente
''
por'0'
, pero agregará un 0 inicial para cualquier número.Resumen de alternativas:
Los colaboradores incluyen a John Fouhy , Tung Nguyen , mVChr , Martin Thoma . y Martijn Pieters.
fuente
str.format()
solo formatear un valor es exagerado. Ir directamente a laformat()
función:format(n, 'b')
. No es necesario analizar el marcador de posición y compararlo con un argumento de esa manera.Como las respuestas anteriores utilizan principalmente el formato (), aquí hay una implementación de f-string.
Salida:
Para mayor comodidad, aquí está el enlace de documentos de Python para literales de cadena formateados: https://docs.python.org/3/reference/lexical_analysis.html#f-strings .
fuente
fuente
Usando numpy pack / unpackbits, son tus mejores amigos.
fuente
uint8
matriz en una matriz de salida binaria de valor. Muy bueno para valores de hasta 255.Para aquellos de nosotros que necesitamos convertir enteros con signo (rango -2 ** (dígitos-1) a 2 ** (dígitos-1) -1) a cadenas binarias complementarias de 2, esto funciona:
Esto produce:
fuente
A menos que no entienda lo que quiere decir con cadena binaria, creo que el módulo que está buscando es struct
fuente
Otra solución más con otro algoritmo, utilizando operadores bit a bit.
Una versión más rápida sin invertir la cadena.
fuente
salida:
fuente
puedes hacer así:
o:
fuente
Aquí está el código que acabo de implementar. ¡Este no es un método, pero puede usarlo como una función lista para usar !
fuente
Aquí hay una solución simple usando la función divmod () que devuelve el recordatorio y el resultado de una división sin la fracción.
fuente
dectobin(10)
resultaron en '0101'fuente
numpy.binary_repr(num, width=None)
Ejemplos del enlace de documentación anterior:
fuente
Solución algo similar
fuente
Aquí hay otra forma de usar las matemáticas regulares, sin bucles, solo recursividad. (El caso trivial 0 no devuelve nada).
fuente
Calculadora con todas las funciones necesarias para DEC, BIN, HEX: (hecho y probado con Python 3.5)
Puede cambiar los números de prueba de entrada y obtener los convertidos.
fuente
fuente
Si estás dispuesto a renunciar a Python "puro" pero obtienes mucha potencia de fuego, está Sage , por ejemplo :
Notarás que regresa como una cadena, así que para usarlo como un número, querrás hacer algo como
fuente
fuente
Encontré un método que usa la operación de matriz para convertir decimal a binario.
E
es entrada de datos decimales,M
es el orden binario.bindata
es salida de datos binarios, que está en un formato de 1 por M matriz binaria.fuente
Aquí hay un simple convertidor binario a decimal que realiza bucles continuamente
fuente
Esta es mi respuesta, funciona bien ...!
fuente
0
? Por ejemplobinary(0)
, ¿obtendrás lo que esperas?