In Binär konvertieren und führende Nullen in Python beibehalten

153

Ich versuche, eine Ganzzahl mit der Funktion bin () in Python in eine Binärzahl umzuwandeln. Es werden jedoch immer die führenden Nullen entfernt, die ich tatsächlich benötige, sodass das Ergebnis immer 8-Bit ist:

Beispiel:

bin(1) -> 0b1

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

Gibt es eine Möglichkeit, dies zu tun?

Niels Sønderbæk
quelle
Siehe auch: Python int to binary? , besonders meine Antwort mit der n-Bit-Darstellung. Nicht genau das gleiche, aber ich kam zu dieser Frage und suchte meine Antwort ...
Martin Thoma

Antworten:

217

Verwenden Sie die format()Funktion :

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

Die format()Funktion formatiert die Eingabe einfach gemäß der Minisprache Formatspezifikation . Das #Format enthält das 0bPräfix, und die 010Größe formatiert die Ausgabe so, dass sie in eine Breite von 10 Zeichen mit 0Auffüllung passt . 2 Zeichen für das 0bPräfix, die anderen 8 für die Binärziffern.

Dies ist die kompakteste und direkteste Option.

Wenn Sie das Ergebnis in eine größere Zeichenfolge einfügen , verwenden Sie ein formatiertes Zeichenfolgenliteral (3.6+) oder verwenden Sie str.format()das zweite Argument für die format()Funktion nach dem Doppelpunkt des Platzhalters {:..}:

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

Selbst wenn Sie nur einen einzelnen Wert formatieren (ohne das Ergebnis in eine größere Zeichenfolge einzufügen), ist die Verwendung eines formatierten Zeichenfolgenliteral schneller als die Verwendung von 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

Aber ich würde das nur verwenden, wenn die Leistung in einer engen Schleife wichtig ist, da format(...)die Absicht besser kommuniziert wird.

Wenn Sie das 0bPräfix nicht wollten , lassen Sie es einfach fallen #und passen Sie die Länge des Feldes an:

>>> format(14, '08b')
'00001110'
Martijn Pieters
quelle
3
Genau das, wonach ich gesucht habe, diese Formatierung ist wirklich hilfreich für mich. Ich habe angefangen, Bitmanipulation zu lernen und habe nach der Bitformatierung für Zahlen in Python gegoogelt. Ich habe es gefunden. Danke dir.
Kratostoical
Funktioniert gut. Kann allerdings etwas sperrig werden. format(192,'08b')+'.'+format(0,'08b')+'.'+format(2,'08b')+'.'+format(33,'08b') 11000000.00000000.00000010.00100001
Stimmen
@ tjt263: Deshalb erkläre ich ausdrücklich, dass Siestr.format(){:..}
Martijn Pieters
1
@ tjt263: zB verwenden f"{192:08b}.{0:08b}.{2:08b}.{33:08b}".
Martijn Pieters
Sehr schön. Ich hätte nie gewusst, dass du das allein mit der Erklärung gemeint hast. Aber jetzt habe ich Ihr Beispiel gesehen, ich werde es wahrscheinlich nie vergessen. Prost.
Stimmen
115
>>> '{:08b}'.format(1)
'00000001'

Siehe: Formatspezifikation Mini-Sprache


Hinweis: Für Python 2.6 oder älter können Sie die ID des Positionsarguments nicht auslassen. :Verwenden Sie sie daher

>>> '{0:08b}'.format(1)
'00000001'      
bwbrowning
quelle
3
Es besteht keine Notwendigkeit, str.format()hier zu verwenden , wann dies format()der Fall ist. Ihnen fehlt das 0bPräfix.
Martijn Pieters
2
@MartijnPieters str.formatist flexibler als format()weil Sie mehrere Variablen gleichzeitig ausführen können . Ich vergesse immer wieder, dass die formatFunktion überhaupt existiert. Zugegeben, in diesem Fall ist es vollkommen ausreichend.
Mark Ransom
1
@MarkRansom: Wenn Sie nur str.format()mit nur einem {}Element und keinem anderen Text verwenden, verwenden Sie keine Zeichenfolgenvorlagen, sondern formatieren einen Wert . In diesem Fall einfach verwenden format(). :-)
Martijn Pieters
30

ich benutze

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

wird gedruckt

'00000001'
rekinyz
quelle
9

Sie können die Mini-Sprache für die Zeichenfolgenformatierung verwenden:

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)

Ausgabe:

'0b00000001'

BEARBEITEN : basierend auf der Idee von @Martijn Pieters

def binary(num, length=8):
    return format(num, '#0{}b'.format(length + 2))
Peter Varo
quelle
2
Dieselbe Formatierungssprache kann verwendet werden, um das Präfix für Sie einzuschließen. Verwenden Sie #. Es gibt auch format(), was erspart, dass Sie eine vollständige Zeichenfolgenvorlage erstellen müssen.
Martijn Pieters
2

Bei Verwendung von Python >= 3.6ist es am saubersten, F-Strings mit String-Formatierung zu verwenden :

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

Erläuterung:

  • var die zu formatierende Variable
  • : Alles danach ist der Formatbezeichner
  • #Verwenden Sie das alternative Formular (fügt das 0bPräfix hinzu)
  • 0 Pad mit Nullen
  • 10Pad auf eine Gesamtlänge von 10 (dies beinhaltet die 2 Zeichen für 0b)
  • b Verwenden Sie eine binäre Darstellung für die Zahl
Ruohola
quelle
Nein, es ist nicht das sauberste, es sei denn, Sie machen mehr mit der Zeichenfolge als nur einen einzelnen Platzhalter . Ansonsten format(var, "#010b")kommuniziert Absicht viel besser. Es ist jedoch die schnellste Option. Aber das wissen Sie schon, richtig, denn ich beschreibe bereits alles, was Sie in meiner Antwort gepostet haben.
Martijn Pieters
1

Manchmal möchten Sie nur einen einfachen Einzeiler:

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

Python 3

Kennzeichen
quelle
1
Beachten Sie, dass das [ ]nicht benötigt werden sollte - join()akzeptiert einen Generatorausdruck. ''.join('{0:08b}'.format(ord(x)) for x in input)
Christoph Burschka
@ChristophBurschka Beachten Sie, dass str.join()ein Generatoreingang vor dem Beitritt zunächst in eine Liste konvertiert wird , da zwei Durchgänge erforderlich sind. Dies beeinträchtigt die Leistung ein wenig und ist es hier eigentlich besser , ein Listenverständnis als einen Generatorausdruck einzugeben. Es ist eine Ausnahme von der Regel.
Martijn Pieters
-1

Sie können so etwas verwenden

("{:0%db}"%length).format(num)
Adam
quelle
2
Bitte verwenden Sie mindestens den Codeblock für Ihr Code-Snippet. Und wenn Sie wirklich möchten, dass es eine gute Antwort ist, fügen Sie auch einige Kommentare hinzu, warum diese Lösung die OP-Frage löst.
β.εηοιτ.βε
Sie müssen keinen anderen Formatierungsstil für Zeichenfolgen verwenden, um eine variable Breite hinzuzufügen. Fügen Sie einfach einen weiteren Platzhalter hinzu:"{:0{l}b}".format(num, l=length)
Martijn Pieters
-1

Sie können die Rjust-String-Methode der Python-Syntax verwenden: string.rjust (Länge, Fillchar) Fillchar ist optional

und für deine Frage kannst du so schreiben

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

also wird es '0b00000001' sein

Jaydeep Mahajan
quelle
Es liegt ein Syntaxfehler vor. Noch wichtiger ist jedoch, dass die Frage, ob es darum geht, eine intin ihre textuelle Binärdarstellung umzuwandeln, überhaupt nicht beantwortet wird . Sie beginnen nicht einmal mit einem int.
Thierry Lathuille
-3

Sie können zfill verwenden:

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

Drucke:

01
10
100

Ich mag diese Lösung, da sie nicht nur bei der Ausgabe der Nummer hilft, sondern wenn Sie sie einer Variablen zuweisen müssen ... zB - x = str (datetime.date.today (). Month) .zfill (2) wird Geben Sie x als '02' für den Monat Februar zurück.

Anshul Garg
quelle
1
Problem mit zfill ist, dass es die binäre Zeichenfolge wie eine Zeichenfolge behandelt und die Nullen vor dem binären 'b'-Indikator hinzufügt ... zB bin(14) gibt es' '0b1110' 'und bin(14).zfill(8) gibt' '000b1110' 'nicht' '0b00001110' ', was erwünscht ist
Shaun