Python int en chaîne binaire?

530

Existe-t-il des méthodes Python prédéfinies pour convertir un entier (ou long) en chaîne binaire en Python?

Il existe une myriade de fonctions dec2bin () sur Google ... Mais j'espérais pouvoir utiliser une fonction / bibliothèque intégrée.

Nate
la source
Pour la prise opposée, pour un algorithme de traitement de chaîne pur, voir ceci .
CopyPasteIt

Réponses:

750

La méthode de format de chaîne de Python peut prendre une spécification de format.

>>> "{0:b}".format(37)
'100101'

Formater les documents de spécification pour Python 2

Formater les documents de spécification pour Python 3

Tung Nguyen
la source
86
str.format()formater une seule valeur est exagéré. Aller directement à la format()fonction : format(n, 'b'). Il n'est pas nécessaire d'analyser l'espace réservé et de le faire correspondre à un argument, passez directement à l'opération de formatage de la valeur elle-même. À utiliser uniquement str.format()si vous devez placer le résultat formaté dans une chaîne plus longue (par exemple, l'utiliser comme modèle).
Martijn Pieters
29
@mike: ou utilisez la spécification de formatage. Ajoutez le nombre de chiffres avec un début 0à la chaîne de formatage: format(10, '016b')formate à 16 chiffres avec des zéros en tête.
Martijn Pieters
Dans ce cas, l' 0entrée "{0:b}"peut être supprimée non? Je veux dire, dans le cas où un seul nombre est formaté, il est correct de le mettre "{:b}", n'est-ce pas?
tomasyany
1
en général, on utilise une représentation de 4/8 / ... bits:"{:08b}".format(37)
Sparkler
2
f "{37: b}" en Python3.7 ou version ultérieure.
DA
471

Si vous recherchez bin()un équivalent àhex() , il a été ajouté en python 2.6.

Exemple:

>>> bin(10)
'0b1010'
John Fouhy
la source
66
Notez également qu'il est plus rapide à faire str(bin(i))[2:](0,369s pour 1000000ops) que "{0:b}".format(i)(0,721s pour 1000000ops)
mVChr
64
@mVChr si quelqu'un convertit des nombres en représentation binaire ASCII, j'espère vraiment que la vitesse n'a pas d'importance.
Nick T
29
@mVChr: str.format()est de toute façon le mauvais outil, vous utiliseriez à la format(i, 'b')place. Tenez compte du fait que cela vous donne également des options de rembourrage et d'alignement; format(i, '016b')pour formater en un nombre binaire 16 bits à remplissage nul. Pour faire de même avec bin()vous devez ajouter un str.zfill()appel: bin(i)[2:].zfill(16)(pas besoin d'appeler str()!). format()La lisibilité et la flexibilité de (la mise en forme dynamique est beaucoup plus difficile avec bin()) sont de bons compromis, n'optimisez pas les performances à moins que vous ne deviez le faire, jusque-là optimisez pour la maintenabilité.
Martijn Pieters
Que signifie [2:]?
zero_cool
4
Bien sûr, avec python 3.6+, vous pouvez maintenant utiliser f"{37:b}".
Luke Davis
63

Python a en fait quelque chose de déjà intégré pour cela, la possibilité d'effectuer des opérations telles que '{0:b}'.format(42), qui vous donnera le modèle de bits (dans une chaîne) pour 42, ou 101010.


Pour une philosophie plus générale, aucune langue ou bibliothèque ne donnera à sa base d'utilisateurs tout ce qu'elle désire. Si vous travaillez dans un environnement qui ne fournit pas exactement ce dont vous avez besoin, vous devez collecter des extraits de code au fur et à mesure de votre développement pour vous assurer de ne jamais avoir à écrire deux fois la même chose. Tels que, par exemple, le pseudo-code:

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 strVal
        else:
            prefix "0" to strVal
        divide intVal by two, rounding down
    return strVal

qui construira votre chaîne binaire en fonction de la valeur décimale. Gardez à l'esprit que c'est un peu générique de pseudo-code qui n'est peut-être pas le plus efficace de le faire, avec les itérations que vous semblez proposer, cela ne fera pas beaucoup de différence. Il s'agit simplement d'une ligne directrice sur la façon de le faire.

L'idée générale est d'utiliser du code de (par ordre de préférence):

  • la langue ou les bibliothèques intégrées.
  • bibliothèques tierces avec des licences appropriées.
  • votre propre collection.
  • quelque chose de nouveau que vous devez écrire (et enregistrer dans votre propre collection pour plus tard).
paxdiablo
la source
1
Quelques bons conseils dans cette réponse. Dommage que le code soit inutilement lent. Vous proposez un algo O (N ^ 2) où un O (N) ferait l'affaire. La partie problématique est dans les lignes s = "1" + set s = "0" + s. Chacun fait une copie inutile du par. Vous devez inverser la chaîne juste avant de la renvoyer à la place.
Andreas Magnusson
@Andreas, ce que j'ai proposé était d'utiliser '{0:b}'.format(42), la méthode lente était simplement un exemple de la façon de le faire de manière générique, qui peut ou non être O (n ^ 2) selon la langue réelle utilisée. Il ne ressemble qu'à Python puisque Python est un langage de pseudo-code idéal, donc je vais changer cela pour que ce soit clair.
paxdiablo
En fait, ce serait un langage assez ésotérique où s = "1" + sn'était pas O (N) quand sest un type chaîne. Peut-être une langue dans laquelle toutes les chaînes sont stockées à l'envers ou chaque caractère est un nœud dans une liste chaînée? Pour toute langue typique, une chaîne est essentiellement un tableau de caractères. Dans ce cas, le préfixe d'une chaîne nécessite qu'une copie soit faite, comment allez-vous mettre le caractère avant les autres caractères?
Andreas Magnusson
Je peux facilement envisager un type de chaîne qui se compose d'un bloc de mémoire où la chaîne est justifiée à droite dans ce bloc et d'un décalage par rapport à son caractère de départ. Pour préfixer un caractère, vous devez alors simplement réduire le décalage et y stocker le caractère. Oui, ce serait ésotérique, mais cela n'a guère de sens pour moi de discuter d'éventuels problèmes dans le monde réel avec un peu de pseudo-code, d' autant plus que vous n'avez probablement pas plus de quelques dizaines de bits / itérations. Même le type de bulle très décrié est adéquat si la taille de vos données est petite :-) Dans tous les cas, je vais ajouter une note sur l'efficacité.
paxdiablo
Bien sûr, si l'efficacité est importante, vous ne choisiriez probablement pas python pour commencer. D'après mon expérience, il arrive assez souvent que le code qui a été écrit naïvement à l'aide d'un algo O (N²) et testé avec un petit ensemble de données soit rapidement utilisé avec un ensemble de données beaucoup plus grand car "il semble fonctionner". Puis tout d'un coup, vous avez du code qui prend des heures à s'exécuter et qui, une fois corrigé, ne peut prendre que quelques secondes. Les algos O (N²) sont insidieux car ils semblent fonctionner pendant un certain temps, mais lorsque vos données évoluent, ils ne le font pas et d'ici là, le gars qui les a écrits a quitté et personne ne sait pourquoi les choses prennent une éternité.
Andreas Magnusson
41

Si vous voulez une représentation textuelle sans le préfixe 0b, vous pouvez utiliser ceci:

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

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

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

Lorsque vous souhaitez une représentation à n bits:

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

Alternativement, si vous préférez avoir une fonction:

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)
Martin Thoma
la source
5
Ou utilisez simplement format(integer, 'b'). bin()est un outil de débogage, spécifiquement destiné à produire la syntaxe littérale d'entier binaire Python , format()est destiné à produire des formats spécifiques.
Martijn Pieters
1
@MartijnPieters Merci beaucoup de l'avoir mentionné. J'ai ajusté ma solutution. Comment savez-vous qu'il bin()s'agit d'un outil de débogage visant à produire la syntaxe littérale d'entier binaire Python? Je n'ai pas trouvé cela dans la documentation.
Martin Thoma
2
De la documentation: Le résultat est une expression Python valide . Son objectif est de produire une expression Python, pas de produire des représentations d'utilisateur final. Il en va de même pour oct()et hex().
Martijn Pieters
4
Plus d'alternatives: Si vous souhaitez rendre la largeur dynamique, str.zfill()vous pouvez utiliser str.format()ou format()avec un deuxième argument dynamique: '{0:0{1}b}'.format(x, n)ou format(b, '0{}b'.format(n)).
Martijn Pieters
@MartijnPieters Wow, merci beaucoup pour cette contribution! Je ne savais pas que c'était possible avec le format. Cependant, je pense que ma réponse actuelle zfillest plus facile à lire et à comprendre que le deuxième argument dynamique, donc je vais garder cela.
Martin Thoma
38

Pour référence:

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

Cette fonction peut convertir un entier positif aussi grand que 18446744073709551615, représenté par une chaîne '1111111111111111111111111111111111111111111111111111111111111111'.

Il peut être modifié pour servir un entier beaucoup plus grand, bien qu'il ne soit pas aussi pratique que "{0:b}".format()ou bin().

kctong529
la source
@GarethDavidson de quelle version s'agit-il? Cette explication explicite pourrait être plus utile à l'avenir lors de la recherche sur Google.
Wolf
C'était la version 2.7 je pense. Je doute que cela fonctionne dans 3.x
Gareth Davidson
17

Un moyen simple de le faire est d'utiliser le format de chaîne, voir cette page .

>> "{0:b}".format(10)
'1010'

Et si vous voulez avoir une longueur fixe de la chaîne binaire, vous pouvez utiliser ceci:

>> "{0:{fill}8b}".format(10, fill='0')
'00001010'

Si le complément à deux est requis, la ligne suivante peut être utilisée:

'{0:{fill}{width}b}'.format((x + 2**n) % 2**n, fill='0', width=n)

où n est la largeur de la chaîne binaire.

Xiang
la source
16

C'est pour python 3 et il garde les zéros de tête!

print(format(0, '08b'))

entrez la description de l'image ici

grepit
la source
1
J'apprécie la réponse simple.
reergymerej
14

one-liner avec lambda :

>>> binary = lambda n: '' if n==0 else binary(n/2) + str(n%2)

tester:

>>> binary(5)
'101'



ÉDITER :

mais alors :(

t1 = time()
for i in range(1000000):
     binary(i)
t2 = time()
print(t2 - t1)
# 6.57236599922

en comparaison avec

t1 = time()
for i in range(1000000):
    '{0:b}'.format(i)
t2 = time()
print(t2 - t1)
# 0.68017411232
Aziz Alto
la source
qui retourne '' pour 0 cependant. La représentation normale de 0 ne serait-elle pas «0»?
dietbacon
si vous voulez voir ce 0 :), vous pouvez le remplacer ''par '0', mais cela ajoutera un 0 de tête pour n'importe quel nombre.
Aziz Alto
11

Résumé des alternatives:

n=42
assert  "-101010" == format(-n, 'b')
assert  "-101010" == "{0:b}".format(-n)
assert  "-101010" == (lambda x: x >= 0 and 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.

Les contributeurs incluent John Fouhy , Tung Nguyen , mVChr , Martin Thoma . et Martijn Pieters.

BobStein-VisiBone
la source
6
str.format()formater une seule valeur est exagéré. Aller directement à la format()fonction: format(n, 'b'). Pas besoin d'analyser l'espace réservé et de le faire correspondre à un argument de cette façon.
Martijn Pieters
10

Comme les réponses précédentes utilisaient principalement le format (), voici une implémentation de f-string.

integer = 7
bit_count = 5
print(f'{integer:0{bit_count}b}')

Production:

00111

Pour plus de commodité, voici le lien des documents python pour les littéraux de chaîne formatés: https://docs.python.org/3/reference/lexical_analysis.html#f-strings .

John Forbes
la source
7
>>> format(123, 'b')
'1111011'
Sandu Ursu
la source
5

Utilisant numpy pack / unpackbits, ils sont vos meilleurs amis.

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)
piège
la source
La question concerne une représentation sous forme de chaîne . Pourtant, c'est exactement ce que je cherchais sans passer par la chaîne! :)
Tom Hale
Le doco dit: Décompresse les éléments d'un uint8tableau dans un tableau de sortie à valeur binaire. Tellement bon pour des valeurs jusqu'à 255.
Tom Hale
5

Pour ceux d'entre nous qui ont besoin de convertir des entiers signés (plage -2 ** (chiffres-1) en 2 ** (chiffres-1) -1) en chaînes binaires complémentaires de 2, cela fonctionne:

def int2bin(integer, digits):
if integer >= 0:
    return bin(integer)[2:].zfill(digits)
else:
    return bin(2**digits + integer)[2:]

Cela produit:

>>> int2bin(10, 8)
'00001010'
>>> int2bin(-10, 8)
'11110110'
>>> int2bin(-128, 8)
'10000000'
>>> int2bin(127, 8)
'01111111'
DeanM
la source
4

À moins que je ne comprenne mal ce que vous entendez par chaîne binaire, je pense que le module que vous recherchez est struct

Van Gale
la source
4

Encore une autre solution avec un autre algorithme, en utilisant des opérateurs au niveau du bit.

def int2bin(val):
    res=''
    while val>0:
        res += str(val&1)
        val=val>>1     # val=val/2 
    return res[::-1]   # reverse the string

Une version plus rapide sans inverser la chaîne.

def int2bin(val):
   res=''
   while val>0:
       res = chr((val&1) + 0x30) + res
       val=val>>1    
   return res 
Reza Abtin
la source
La deuxième version n'est certainement pas plus rapide car vous vous retrouvez avec quelque chose comme un algorithme O (N ^ 2) au lieu d'un O (N). J'ai vu des choses comme ça tuer une application (en termes de performances) parce que le développeur pensait que faire une passe supplémentaire à la fin était plus lent que de faire des choses supplémentaires dans la première boucle. Une fois réparé, le temps de fonctionnement passe de quelques jours à quelques secondes.
Andreas Magnusson
4
def binary(decimal) :
    otherBase = ""
    while decimal != 0 :
        otherBase  =  str(decimal % 2) + otherBase
        decimal    //=  2
    return otherBase

print binary(10)

production:

1010

mukundan
la source
4

vous pouvez faire comme ça:

bin(10)[2:]

ou :

f = str(bin(10))
c = []
c.append("".join(map(int, f[2:])))
print c
Skiller Dz
la source
bin (n) .replace ("0b", "")
sanner little
3

Voici le code que je viens d'implémenter. Ce n'est pas une méthode mais vous pouvez l'utiliser comme une fonction prête à l'emploi !

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
quents
la source
3

voici une solution simple utilisant la fonction divmod () qui retourne le rappel et le résultat d'une division sans la fraction.

def dectobin(number):
    bin = ''
    while (number >= 1):
        number, rem = divmod(number, 2)
        bin = bin + str(rem)
    return bin
user210021
la source
Besoin de débogage. L'appel a dectobin(10)abouti à '0101'
Nate
3
n=input()
print(bin(n).replace("0b", ""))
dblaze
la source
3

numpy.binary_repr(num, width=None)

Exemples du lien de documentation ci-dessus:

>>> np.binary_repr(3)
'11'
>>> np.binary_repr(-3)
'-11'
>>> np.binary_repr(3, width=4)
'0011'

Le complément à deux est renvoyé lorsque le nombre d'entrée est négatif et que la largeur est spécifiée:

>>> np.binary_repr(-3, width=3)
'101'
>>> np.binary_repr(-3, width=5)
'11101'
Tom Hale
la source
2

Solution assez similaire

def to_bin(dec):
    flag = True
    bin_str = ''
    while flag:
        remainder = dec % 2
        quotient = dec / 2
        if quotient == 0:
            flag = False
        bin_str += str(remainder)
        dec = quotient
    bin_str = bin_str[::-1] # reverse the string
    return bin_str 
Chandler
la source
2

Voici encore une autre façon d'utiliser les mathématiques régulières, pas de boucles, seulement la récursivité. (Le cas trivial 0 ne renvoie rien).

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']
ergonaute
la source
2

Calculatrice avec toutes les fonctions nécessaires pour DEC, BIN, HEX: (fabriqué et testé avec Python 3.5)

Vous pouvez modifier les numéros de test d'entrée et obtenir ceux convertis.

# CONVERTER: DEC / BIN / HEX

def 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)



## PRINTING
print('------- 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')
HKC72
la source
2

Pour calculer un binaire de nombres:

print("Binary is {0:>08b}".format(16))

Pour calculer la décimale hexa d'un nombre :

print("Hexa Decimal is {0:>0x}".format(15))

Pour calculer tous les no binaires jusqu'à 16 ::

for i in range(17):
   print("{0:>2}: binary is {0:>08b}".format(i))

Pour calculer Hexa décimal no till 17

 for i in range(17):
    print("{0:>2}: Hexa Decimal is {0:>0x}".format(i))
##as 2 digit is enogh for hexa decimal representation of a number
Rajesh Kumar Sahoo
la source
1

Si vous êtes prêt à abandonner Python "pur" mais à gagner beaucoup de puissance de feu, il y a Sage - exemple ici :

sage: a = 15
sage: a.binary()
'1111'

Vous remarquerez qu'il retourne sous forme de chaîne, donc pour l'utiliser comme un nombre, vous voudriez faire quelque chose comme

sage: eval('0b'+b)
15
kcrisman
la source
1
try:
    while True:
        p = ""
        a = input()
        while a != 0:
            l = a % 2
            b = a - l
            a = b / 2
            p = str(l) + p
        print(p)
except:
    print ("write 1 number")
user7930187
la source
6
Je pourrais vouloir ajouter quelques explications à ce que vous y avez fait.
Artless
1

J'ai trouvé une méthode utilisant une opération matricielle pour convertir des décimales en binaires.

import numpy as np
E_mat = np.tile(E,[1,M])
M_order = pow(2,(M-1-np.array(range(M)))).T
bindata = np.remainder(np.floor(E_mat /M_order).astype(np.int),2)

Eest l'entrée des données décimales, Mest les ordres binaires. bindataest une sortie de données binaires, au format 1 par M matrice binaire.

Galle He
la source
0

Voici un simple convertisseur binaire en décimal qui boucle en continu

t = 1
while t > 0:
    binaryNumber = input("Enter a binary No.")
    convertedNumber = int(binaryNumber, 2)

    print(convertedNumber)

print("")
Spencer Layland
la source
Il s'agit de l'ordre inverse de ce que souhaite le PO. Ils recherchent l'int en binaire. Vous fournissez binaire à int.
Cecilia
0

C'est ma réponse ça marche bien ..!

def binary(value) :
    binary_value = ''
    while value !=1  :
        binary_value += str(value%2)
        value = value//2
    return '1'+binary_value[::-1]
Charunie Hansika AM
la source
Et si vous transmettez la valeur 0? Par exemple, binary(0)obtiendrez-vous ce que vous attendez?
Andreas Magnusson