Python int in stringa binaria?


530

Esistono metodi Python predefiniti per convertire un numero intero (o Long) in una stringa binaria in Python?

Esistono una miriade di funzioni di dec2bin () su Google ... Ma speravo di poter usare una funzione / libreria integrata.


Per il contrario, per un puro algoritmo di elaborazione delle stringhe, vedi questo .
CopyPasteIt

Risposte:


750

Il metodo di formato stringa di Python può richiedere una specifica di formato.

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

Formatta i documenti delle specifiche per Python 2

Formatta i documenti delle specifiche per Python 3


86
str.format()solo formattare un valore è eccessivo. Vai direttamente alla format()funzione di : format(n, 'b'). Non è necessario analizzare il segnaposto e associarlo a un argomento, procedere direttamente per l'operazione di formattazione del valore stesso. Utilizzare solo str.format()se è necessario posizionare il risultato formattato in una stringa più lunga (ad es. Usarlo come modello).
Martijn Pieters

29
@mike: oppure usa le specifiche di formattazione. Aggiungi il numero di cifre con un iniziale 0alla stringa di formattazione: format(10, '016b')formatta a 16 cifre con zeri iniziali.
Martijn Pieters

In questo caso, 0in "{0:b}"può essere lasciato cadere no? Voglio dire, nel caso in cui venga formattato un solo numero, è corretto metterlo "{:b}", no?
tomasyany,

1
in genere si usa la rappresentazione a 4/8 / ... bit:"{:08b}".format(37)
Sparkler

2
f "{37: b}" in Python3.7 o successivo.
DA

471

Se stai cercando bin() come equivalente ahex() , è stato aggiunto in Python 2.6.

Esempio:

>>> bin(10)
'0b1010'

66
Nota anche che è più veloce da fare str(bin(i))[2:](0.369s per 1000000ops) rispetto a "{0:b}".format(i)(0.721s per 1000000ops)
mVChr

64
@mVChr se qualcuno sta convertendo i numeri in una rappresentazione binaria ASCII, spero davvero che la velocità non abbia importanza.
Nick T,

29
@mVChr: str.format()è lo strumento sbagliato comunque, che useresti format(i, 'b')invece. Prendi in considerazione ciò che ti dà anche le opzioni di riempimento e allineamento; format(i, '016b')per formattare in un numero binario a zero bit a 16 bit. Per fare lo stesso con bin()dovresti aggiungere una str.zfill()chiamata: bin(i)[2:].zfill(16)(non c'è bisogno di chiamare str()!). format()La leggibilità e la flessibilità (la formattazione dinamica è molto più difficile con bin()) sono grandi compromessi, non ottimizzare le prestazioni a meno che non sia necessario, fino ad allora ottimizzare per la manutenibilità.
Martijn Pieters

Cosa significa [2:]?
zero_cool

4
Ovviamente, con Python 3.6+ è ora possibile utilizzare f"{37:b}".
Luke Davis,

63

Python in realtà ha qualcosa già costruito in per questo, la capacità di fare operazioni come '{0:b}'.format(42), che vi darà la sequenza di bit (in una stringa) per 42o 101010.


Per una filosofia più generale, nessuna lingua o biblioteca fornirà alla sua base di utenti tutto ciò che desiderano. Se lavori in un ambiente che non fornisce esattamente ciò di cui hai bisogno, dovresti raccogliere frammenti di codice mentre sviluppi per assicurarti di non dover mai scrivere la stessa cosa due volte. Come, ad esempio, lo pseudo-codice:

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

che costruirà la tua stringa binaria in base al valore decimale. Tieni presente che è un po 'di pseudo-codice generico che potrebbe non essere il più efficiente di farlo, tuttavia, con le iterazioni che sembra stia proponendo, non farà molta differenza. In realtà è solo inteso come una linea guida su come potrebbe essere fatto.

L'idea generale è di usare il codice da (in ordine di preferenza):

  • la lingua o le librerie integrate.
  • librerie di terze parti con licenze adeguate.
  • la tua collezione.
  • qualcosa di nuovo che devi scrivere (e salvare nella tua raccolta per dopo).

1
Alcuni buoni consigli in questa risposta. Peccato che il codice sia inutilmente lento. Proponi un algo O (N ^ 2) dove farebbe un O (N). La parte problematica è nelle righe s = "1" + se s = "0" + s. Ognuno fa una copia non necessaria di s. Dovresti invece invertire la stringa appena prima di restituirla.
Andreas Magnusson,

@Andreas, quello che ho proposto era di usare '{0:b}'.format(42), il metodo lento era semplicemente un esempio di come farlo in modo generico, che può essere o non essere O (n ^ 2) a seconda del linguaggio effettivamente utilizzato. Sembra solo Python poiché Python è un linguaggio pseudo-codice ideale, quindi lo cambierò per chiarirlo.
paxdiablo,

In realtà sarebbe un linguaggio piuttosto esoterico dove s = "1" + snon c'era O (N) quando sè un tipo di stringa. Forse una lingua in cui tutte le stringhe sono memorizzate all'indietro o ogni carattere è un nodo in un elenco collegato? Per qualsiasi linguaggio tipico una stringa è fondamentalmente un array di caratteri. In tal caso, il prefisso di una stringa richiede che venga creata una copia, in quale altro modo metterai il carattere prima degli altri caratteri?
Andreas Magnusson,

Posso facilmente immaginare un tipo di stringa che consiste in un blocco di memoria in cui la stringa è giustificata a destra all'interno di quel blocco e un offset rispetto al suo carattere iniziale. Per aggiungere un prefisso a un personaggio, è sufficiente ridurre l'offset e memorizzare il personaggio lì. Sì, sarebbe esoterico ma per me ha poco senso discutere su possibili problemi del mondo reale con un po 'di pseudo-codice, soprattutto perché non è probabile che tu abbia più di qualche dozzina di bit / iterazioni. Anche l'ordinamento a bolle molto diffamato è adeguato se la dimensione dei tuoi dati è piccola :-) In ogni caso, aggiungerò una nota sull'efficienza.
paxdiablo,

Certo, se l'efficienza è importante, probabilmente non sceglierai Python per cominciare. Tuttavia, nella mia esperienza, capita abbastanza spesso che il codice che è stato scritto ingenuamente usando un algo O (N²) e testato con un piccolo set di dati venga rapidamente utilizzato con un set di dati molto più grande perché "sembra funzionare". Quindi all'improvviso hai un codice che impiega ore per essere eseguito e che quando risolto può richiedere solo pochi secondi. O (N²) algos sono insidiosi perché sembrano funzionare per un po 'ma quando i tuoi dati si ridimensionano non lo fanno e da allora il ragazzo che li ha scritti ha smesso e nessuno sa perché le cose durano per sempre.
Andreas Magnusson,

41

Se si desidera una rappresentazione testuale senza il prefisso 0b, è possibile utilizzare questo:

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

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

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

Quando si desidera una rappresentazione n-bit:

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

In alternativa, se preferisci avere una funzione:

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)

5
O semplicemente usa format(integer, 'b'). bin()è uno strumento di debug, specificamente mirato a produrre la sintassi letterale intera binaria Python , format()è pensato per produrre formati specifici.
Martijn Pieters

1
@MartijnPieters Grazie mille per averlo menzionato. Ho modificato la mia soluzione. Come fai a sapere che bin()è uno strumento di debug volto a produrre la sintassi letterale intera binaria Python? Non sono riuscito a trovarlo nella documentazione.
Martin Thoma,

2
Dalla documentazione: il risultato è un'espressione Python valida . Lo scopo è produrre un'espressione Python, non produrre rappresentazioni dell'utente finale. Lo stesso vale per oct()e hex().
Martijn Pieters

4
Altre alternative: se vuoi rendere dinamica la larghezza, invece di str.zfill()usare str.format()o format()con un secondo argomento dinamico: '{0:0{1}b}'.format(x, n)o format(b, '0{}b'.format(n)).
Martijn Pieters

@MartijnPieters Wow, grazie mille per questo contributo! Non sapevo che questo fosse possibile con il formato. Tuttavia, penso che la mia risposta attuale zfillsia più facile da leggere e comprendere rispetto al secondo argomento dinamico, quindi la terrò.
Martin Thoma,

38

Come referenza:

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

Questa funzione può convertire un numero intero positivo grande come 18446744073709551615, rappresentato come stringa'1111111111111111111111111111111111111111111111111111111111111111' .

Può essere modificato per servire un numero intero molto più grande, anche se potrebbe non essere utile come "{0:b}".format()o bin().


@GarethDavidson quale versione è questa? Detto questo esplicitamente potrebbe essere di maggiore utilità futura quando si cerca su Google.
Lupo,

Era la versione 2.7, credo. Dubito che funzionerebbe in 3.x
Gareth Davidson,

17

Un modo semplice per farlo è usare il formato stringa, vedi questa pagina .

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

E se vuoi avere una lunghezza fissa della stringa binaria, puoi usare questo:

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

Se è richiesto il complemento a due, è possibile utilizzare la seguente riga:

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

dove n è la larghezza della stringa binaria.


16

Questo è per Python 3 e mantiene gli zeri iniziali!

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

inserisci qui la descrizione dell'immagine


1
Apprezzo la risposta semplice.
reergymerej,

14

one-liner con lambda :

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

test:

>>> binary(5)
'101'



MODIFICARE :

ma allora :(

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

in confronto a

t1 = time()
for i in range(1000000):
    '{0:b}'.format(i)
t2 = time()
print(t2 - t1)
# 0.68017411232

che restituisce '' per 0 però. La rappresentazione normale per 0 non sarebbe '0'?
dietbacon,

se vuoi vedere quello 0 :), puoi sostituirlo ''con '0', ma aggiungerà uno 0 iniziale per qualsiasi numero.
Aziz Alto,

11

Riepilogo delle alternative:

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.

Tra i collaboratori ci sono John Fouhy , Tung Nguyen , mVChr , Martin Thoma . e Martijn Pieters.


6
str.format()solo formattare un valore è eccessivo. Vai direttamente alla format()funzione di: format(n, 'b'). Non è necessario analizzare il segnaposto e associarlo a una discussione in quel modo.
Martijn Pieters



5

Usando numpy pack / unpackbits, sono i tuoi migliori amici.

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 domanda riguarda una rappresentazione di stringhe . Tuttavia, è successo che fosse proprio quello che stavo cercando senza passare prima con la stringa! :)
Tom Hale

Il doco dice: decomprime gli elementi di un uint8array in un array di output a valore binario. Così buono per valori fino a 255.
Tom Hale

5

Per quelli di noi che hanno bisogno di convertire numeri interi con segno (intervallo -2 ** (cifre-1) in 2 ** (cifre-1) -1) nelle stringhe binarie del complemento di 2, questo funziona:

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

Questo produce:

>>> int2bin(10, 8)
'00001010'
>>> int2bin(-10, 8)
'11110110'
>>> int2bin(-128, 8)
'10000000'
>>> int2bin(127, 8)
'01111111'


4

Ancora un'altra soluzione con un altro algoritmo, usando operatori bit per bit.

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

Una versione più veloce senza invertire la stringa.

def int2bin(val):
   res=''
   while val>0:
       res = chr((val&1) + 0x30) + res
       val=val>>1    
   return res 

La seconda versione non è sicuramente più veloce quando si arriva a qualcosa di simile a un algoritmo O (N ^ 2) anziché a O (N). Ho visto cose come questa uccidere un'applicazione (per quanto riguarda le prestazioni) perché lo sviluppatore pensava che fare un passaggio extra alla fine fosse più lento rispetto a fare qualcosa in più nel primo ciclo. Una volta risolto, il tempo di esecuzione è diminuito da giorni a secondi.
Andreas Magnusson,

4
def binary(decimal) :
    otherBase = ""
    while decimal != 0 :
        otherBase  =  str(decimal % 2) + otherBase
        decimal    //=  2
    return otherBase

print binary(10)

produzione:

1010


4

puoi fare così:

bin(10)[2:]

o :

f = str(bin(10))
c = []
c.append("".join(map(int, f[2:])))
print c

bin (n) .replace ("0b", "")
sanner piccolo

3

Ecco il codice che ho appena implementato. Questo non è un metodo ma puoi usarlo come una funzione pronta per l'uso !

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

3

qui è una soluzione semplice che utilizza il fucmtion divmod () che restituisce il promemoria e il risultato di una divisione senza la frazione.

def dectobin(number):
    bin = ''
    while (number >= 1):
        number, rem = divmod(number, 2)
        bin = bin + str(rem)
    return bin

Richiede debug. La chiamata ha dectobin(10)portato a "0101"
Nate,


3

numpy.binary_repr(num, width=None)

Esempi dal link della documentazione sopra:

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

Il complemento a due viene restituito quando il numero di input è negativo e viene specificata la larghezza:

>>> np.binary_repr(-3, width=3)
'101'
>>> np.binary_repr(-3, width=5)
'11101'

2

Soluzione un po 'simile

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 

2

Ecco un altro modo di usare la matematica normale, nessun loop, solo la ricorsione. (Il caso Trivial 0 non restituisce nulla).

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']

2

Calcolatrice con tutte le funzioni necessarie per DEC, BIN, HEX: (realizzata e testata con Python 3.5)

È possibile modificare i numeri dei test di input e ottenere quelli convertiti.

# 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')

2

Per calcolare il numero binario di numeri:

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

Per calcolare il decimale Hexa di un numero :

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

Per calcolare tutto il numero binario fino a 16 ::

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

Per calcolare il decimale Hexa no fino a 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

1

Se sei disposto a rinunciare a Python "puro" ma ottieni molta potenza di fuoco, c'è Sage - esempio qui :

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

Noterai che ritorna come una stringa, quindi per usarlo come numero vorresti fare qualcosa del genere

sage: eval('0b'+b)
15

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

6
Potrebbe voler aggiungere qualche spiegazione a quello che hai fatto lì.
Artless,

1

Ho trovato un metodo che utilizza l'operazione matrice per convertire i decimali in binari.

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)

Evengono inseriti dati decimali, Msono gli ordini binari. bindatavengono emessi dati binari, che è in un formato 1 con matrice binaria M.


0

Ecco un semplice convertitore da binario a decimale che esegue un loop continuo

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

    print(convertedNumber)

print("")

Questo è l'ordine inverso di ciò che l'OP vuole. Stanno cercando int in binario. Fornisci binario a int.
Cecilia,

0

Questa è la mia risposta funziona bene ..!

def binary(value) :
    binary_value = ''
    while value !=1  :
        binary_value += str(value%2)
        value = value//2
    return '1'+binary_value[::-1]

Cosa succede se si passa il valore 0? Ad esempio binary(0), otterrai ciò che ti aspetti?
Andreas Magnusson,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.