Converti in binario e mantieni gli zeri iniziali in Python


154

Sto provando a convertire un numero intero in binario usando la funzione bin () in Python. Tuttavia, rimuove sempre gli zeri iniziali, di cui ho effettivamente bisogno, in modo che il risultato sia sempre a 8 bit:

Esempio:

bin(1) -> 0b1

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

C'è un modo per farlo?


Vedi anche: Python int in binario? , in particolare la mia risposta con la rappresentazione n-bit. Non esattamente lo stesso, ma sono arrivato a questa domanda cercando la mia risposta ...
Martin Thoma,

Risposte:


220

Usa la format()funzione :

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

La format()funzione formatta semplicemente l'input seguendo il mini linguaggio Specifica formato . La #rende il formato includono il 0bprefisso, e 010un formato di uscita per adattarsi a 10 caratteri larghezza, con 0imbottitura; 2 caratteri per il 0bprefisso, gli altri 8 per le cifre binarie.

Questa è l'opzione più compatta e diretta.

Se stai inserendo il risultato in una stringa più grande, usa una stringa formattata letterale (3.6+) o usa str.format()e inserisci il secondo argomento per la format()funzione dopo i due punti del segnaposto {:..}:

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

Come succede, anche solo per la formattazione di un singolo valore (quindi senza mettere il risultato in una stringa più grande), usare una stringa formattata letterale è più veloce dell'uso 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

Ma lo userei solo se le prestazioni in un circuito ristretto contano, poiché format(...)comunica meglio l'intento.

Se non si desidera il 0bprefisso, è sufficiente rilasciare #e regolare la lunghezza del campo:

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

3
Esattamente quello che stavo cercando, questa formattazione è davvero utile per me. Ho iniziato a studiare la manipolazione dei bit e stavo cercando su Google la formattazione dei bit per i numeri in Python. Trovato questo. Grazie.
Kratostoical,

Funziona bene. Può diventare un po 'ingombrante però. format(192,'08b')+'.'+format(0,'08b')+'.'+format(2,'08b')+'.'+format(33,'08b') 11000000.00000000.00000010.00100001
Voci

@ tjt263: Ecco perché dichiaro esplicitamente che se stai inserendo il risultato in una stringa più grande, usa una stringa formattata letterale (3.6+) o usa str.format()e metti il ​​secondo argomento per la funzione format () dopo i due punti del segnaposto {:..}:
Martijn Pieters

1
@ tjt263: ad es f"{192:08b}.{0:08b}.{2:08b}.{33:08b}". uso .
Martijn Pieters

Molto bella. Non avrei mai saputo che intendevi solo per spiegazione. Ma ora ho visto il tuo esempio, probabilmente non lo dimenticherò mai. Saluti.
Voci

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

Vedi: Specifica del formato Mini-lingua


Nota per Python 2.6 o precedente, non è possibile omettere prima l'identificatore dell'argomento posizionale :, quindi utilizzare

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

3
Non è necessario utilizzare str.format()qui quando format()lo farà. Manca il 0bprefisso.
Martijn Pieters

2
@MartijnPieters, str.formatè più flessibile che format()perché ti permetterà di fare più variabili contemporaneamente. Continuo a dimenticare che la formatfunzione esiste persino. Certamente è perfettamente adeguato in questo caso.
Mark Ransom,

1
@MarkRansom: Esattamente, quando si utilizza solo str.format()con un solo {}elemento, nessun altro testo, non si utilizza il modello di stringa, si sta formattando un valore . In tal caso basta usare format(). :-)
Martijn Pieters

30

sto usando

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

stamperà

'00000001'

9

È possibile utilizzare il mini linguaggio di formattazione delle stringhe:

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

demo:

print binary(1)

Produzione:

'0b00000001'

EDIT: basato sull'idea di @Martijn Pieters

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

2
La stessa lingua di formattazione può essere utilizzata per includere il prefisso per te. Usa #. C'è anche format(), che ti fa risparmiare dover fare un modello di stringa completo.
Martijn Pieters

2

Quando si usa Python >= 3.6, il modo più pulito è usare le stringhe f con formattazione delle stringhe :

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

Spiegazione:

  • var la variabile da formattare
  • : tutto ciò che segue è l'identificatore di formato
  • # usa il modulo alternativo (aggiunge il 0b prefisso)
  • 0 pad con zeri
  • 10 pad per una lunghezza totale di 10 (questo include i 2 caratteri per 0b )
  • b usa la rappresentazione binaria per il numero

No, non è il più pulito, a meno che tu non faccia di più con la stringa di un singolo segnaposto . Altrimenti format(var, "#010b")comunica l' intento molto meglio. È, tuttavia, l'opzione più veloce. Ma lo sai già, giusto, perché già copro tutto ciò che hai pubblicato nella mia risposta.
Martijn Pieters

1

A volte vuoi solo una semplice fodera:

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

Python 3


1
Si noti che [ ]non dovrebbe essere necessario: join()accetta un'espressione del generatore. ''.join('{0:08b}'.format(ord(x)) for x in input)
Christoph Burschka,

@ChristophBurschka nota che poiché è str.join()necessario effettuare due passaggi, un input del generatore viene prima convertito in un elenco prima di unirsi. Questo richiede un po 'di stress sulle prestazioni e in realtà è meglio qui passare in una comprensione di lista piuttosto che in un'espressione del generatore. È uno se loro eccezioni alla regola.
Martijn Pieters

-1

Puoi usare qualcosa del genere

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

2
Utilizza almeno il blocco di codice per lo snippet di codice. E se vuoi davvero che sia una buona risposta, aggiungi anche alcuni commenti sul perché questa soluzione sta risolvendo la domanda OP.
β.εηοιτ.βε

Non è necessario utilizzare uno stile di formattazione delle stringhe diverso solo per aggiungere una larghezza variabile. Basta aggiungere un altro segnaposto:"{:0{l}b}".format(num, l=length)
Martijn Pieters

-1

puoi usare il metodo rjust string della sintassi di python: string.rjust (lunghezza, fillchar) fillchar è opzionale

e per la tua domanda puoi scrivere così

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

quindi sarà "0b00000001"


Si è verificato un errore di sintassi. Ma soprattutto, non risponde affatto alla domanda, che riguarda la conversione di una intnella sua rappresentazione binaria testuale; non inizi nemmeno con un int.
Thierry Lathuille,

-3

Puoi usare zfill:

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

stampe:

01
10
100

Mi piace questa soluzione, poiché aiuta non solo quando si stampa il numero, ma quando è necessario assegnarlo a una variabile ... ad es. - x = str (datetime.date.today (). Month) .zfill (2) ritorna x come '02' per il mese di febbraio.


1
problema con zfill è che tratta la stringa binaria come una stringa e aggiunge gli zeri prima dell'indicatore binario 'b' ... es. bin(14) dà `` 0b1110 '' e bin(14).zfill(8) dà `` 000b1110 '' non `` 0b00001110 '' che è quello che è desiderato
Shaun,
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.