Python int zu binärem String?

530

Gibt es vordefinierte Python-Methoden, um eine Ganzzahl (oder Long) in Python in eine Binärzeichenfolge zu konvertieren?

Es gibt eine Vielzahl von dec2bin () -Funktionen bei Google ... Aber ich hatte gehofft, ich könnte eine integrierte Funktion / Bibliothek verwenden.

Nate
quelle
Für das Gegenteil, für einen reinen String-Verarbeitungsalgorithmus, siehe dies .
CopyPasteIt

Antworten:

750

Die String-Formatmethode von Python kann eine Formatspezifikation annehmen.

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

Formatieren Sie die Spezifikationsdokumente für Python 2

Formatieren Sie die Spezifikationsdokumente für Python 3

Tung Nguyen
quelle
86
str.format()Nur einen Wert zu formatieren, ist übertrieben. Gehen Sie direkt zur format()Funktion : format(n, 'b'). Es ist nicht erforderlich, den Platzhalter zu analysieren und ihn einem Argument zuzuordnen. Führen Sie direkt die Wertformatierungsoperation selbst aus. Nur verwenden, str.format()wenn Sie das formatierte Ergebnis in eine längere Zeichenfolge einfügen müssen (z. B. als Vorlage verwenden).
Martijn Pieters
29
@mike: Oder verwenden Sie die Formatierungsspezifikation. Fügen Sie die Anzahl der Stellen mit einem führenden 0Wert zur Formatierungszeichenfolge hinzu: format(10, '016b')Formate mit 16 Stellen und führenden Nullen.
Martijn Pieters
In diesem Fall kann das 0In "{0:b}"nicht fallen gelassen werden? Ich meine, wenn nur eine Zahl formatiert wird, ist es richtig zu sagen "{:b}", nicht wahr?
Tomasyany
1
normalerweise würde man 4/8 / ... Bit-Darstellung verwenden:"{:08b}".format(37)
Wunderkerze
2
f "{37: b}" in Python3.7 oder höher.
DA
471

Wenn Sie nach bin()einem Äquivalent suchen hex(), wurde es in Python 2.6 hinzugefügt.

Beispiel:

>>> bin(10)
'0b1010'
John Fouhy
quelle
66
Beachten Sie auch, dass es schneller geht str(bin(i))[2:](0,369s für 1000000ops) als "{0:b}".format(i)(0,721s für 1000000ops)
mVChr
64
@mVChr Wenn jemand Zahlen in eine ASCII-Binärdarstellung konvertiert, hoffe ich wirklich, dass Geschwindigkeit keine Rolle spielt.
Nick T
29
@mVChr: str.format()ist sowieso das falsche Tool, das Sie format(i, 'b')stattdessen verwenden würden. Berücksichtigen Sie, dass Sie dadurch auch Optionen zum Auffüllen und Ausrichten erhalten. format(i, '016b')Formatieren auf eine 16-Bit-Null-aufgefüllte Binärzahl. Um dasselbe mit zu tun, müssten bin()Sie einen str.zfill()Anruf hinzufügen : bin(i)[2:].zfill(16)(kein Anruf erforderlich str()!). format()Die Lesbarkeit und Flexibilität (dynamische Formatierung ist viel schwieriger bin()) sind große Kompromisse. Optimieren Sie die Leistung nicht, es sei denn, Sie müssen, bis dahin optimieren Sie die Wartbarkeit.
Martijn Pieters
Was bedeutet [2:]?
zero_cool
4
Natürlich können Sie jetzt mit Python 3.6+ verwenden f"{37:b}".
Luke Davis
63

Python tatsächlich tut etwas dafür gebaut hat bereits die Fähigkeit , Operationen, wie zu tun '{0:b}'.format(42), was Ihnen das Bitmuster geben (in einem String) für 42oder 101010.


Für eine allgemeinere Philosophie gibt keine Sprache oder Bibliothek ihrer Benutzerbasis alles , was sie sich wünschen. Wenn Sie in einer Umgebung arbeiten, die nicht genau das bietet, was Sie benötigen, sollten Sie während der Entwicklung Codeausschnitte sammeln, um sicherzustellen, dass Sie nie zweimal dasselbe schreiben müssen. Wie zum Beispiel der Pseudocode:

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

Dadurch wird Ihre Binärzeichenfolge basierend auf dem Dezimalwert erstellt. Denken Sie daran , dass ein generisch bisschen Pseudo-Code ist das nicht das sein kann , am meisten jedoch effiziente Art und Weise tun, mit den Iterationen Sie scheinen zu schlagen, wird es nicht viel Unterschied machen. Es ist wirklich nur als Richtlinie gedacht, wie es gemacht werden könnte.

Die allgemeine Idee ist, Code von (in der Reihenfolge der Präferenz) zu verwenden:

  • die Sprache oder die eingebauten Bibliotheken.
  • Bibliotheken von Drittanbietern mit geeigneten Lizenzen.
  • Ihre eigene Sammlung.
  • etwas Neues, das Sie schreiben müssen (und für später in Ihrer eigenen Sammlung speichern müssen).
paxdiablo
quelle
1
Einige gute Ratschläge in dieser Antwort. Nur schade, dass der Code unnötig langsam ist. Sie schlagen ein O (N ^ 2) -Algo vor, wo ein O (N) tun würde. Der problematische Teil ist in den s = "1" + sund s = "0" + sZeilen. Jeder macht eine unnötige Kopie von s. Sie sollten die Zeichenfolge umkehren, bevor Sie sie zurückgeben.
Andreas Magnusson
@Andreas, was ich vorgeschlagen habe, war '{0:b}'.format(42), die langsame Methode war einfach ein Beispiel dafür, wie man es generisch macht, was abhängig von der tatsächlich verwendeten Sprache O (n ^ 2) sein kann oder nicht. Es sieht nur nach Python aus, da Python eine ideale Pseudocodesprache ist, also werde ich das ändern, um es klar zu machen.
paxdiablo
Eigentlich wäre es eine ziemlich esoterische Sprache, in s = "1" + sder nicht O (N) ist, wenn ses sich um einen Zeichenfolgentyp handelt. Vielleicht eine Sprache, in der alle Zeichenfolgen rückwärts gespeichert sind oder jedes Zeichen ein Knoten in einer verknüpften Liste ist? Für jede typische Sprache ist eine Zeichenfolge im Grunde ein Array von Zeichen. In diesem Fall muss für das Präfixieren einer Zeichenfolge eine Kopie erstellt werden. Wie können Sie das Zeichen sonst vor die anderen Zeichen stellen?
Andreas Magnusson
Ich kann mir leicht einen Zeichenfolgentyp vorstellen, der aus einem Speicherblock besteht, in dem die Zeichenfolge innerhalb dieses Blocks rechtsbündig ist, und einem Versatz zu ihrem Startzeichen. Um einem Zeichen ein Präfix voranzustellen, reduzieren Sie einfach den Versatz und speichern das Zeichen dort. Ja, das wäre esoterisch, aber es macht für mich wenig Sinn, über mögliche Probleme in der realen Welt mit ein bisschen Pseudocode zu streiten, zumal Sie wahrscheinlich nicht mehr als ein paar Dutzend Bits / Iterationen haben. Sogar die stark bösartige Blasensortierung ist ausreichend, wenn Ihre Datengröße klein ist :-) Auf jeden Fall werde ich einen Hinweis zur Effizienz hinzufügen.
paxdiablo
Sicher, wenn Effizienz wichtig ist, würden Sie wahrscheinlich zunächst nicht Python wählen. Nach meiner Erfahrung kommt es jedoch häufig vor, dass Code, der naiv mit einem O (N²) -Algo geschrieben und mit einem kleinen Datensatz getestet wurde, schnell mit einem viel größeren Datensatz verwendet wird, weil "er zu funktionieren scheint". Dann haben Sie plötzlich Code, dessen Ausführung Stunden dauert und der, wenn er behoben ist, nur Sekunden dauern kann. O (N²) -Algen sind heimtückisch, weil sie eine Weile zu funktionieren scheinen, aber wenn Ihre Daten skalieren, tun sie dies nicht und bis dahin hat der Typ, der sie geschrieben hat, aufgehört und niemand weiß, warum die Dinge ewig dauern.
Andreas Magnusson
41

Wenn Sie eine Textdarstellung ohne das Präfix 0b wünschen, können Sie Folgendes verwenden:

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

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

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

Wenn Sie eine n-Bit-Darstellung wünschen:

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

Alternativ, wenn Sie eine Funktion bevorzugen:

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
quelle
5
Oder einfach benutzen format(integer, 'b'). bin()ist ein Fehlersuchwerkzeug, das speziell darauf ausgerichtet auf die Herstellung Python binary integer Literalsyntax , format()zu produzieren spezifische Formate gemeint ist.
Martijn Pieters
1
@MartijnPieters Vielen Dank, dass Sie es erwähnt haben. Ich habe meine Lösung angepasst. Woher wissen Sie, dass dies bin()ein Debugging-Tool ist, mit dem die Python-Binär-Ganzzahl-Literal-Syntax erstellt werden soll? Ich konnte das in der Dokumentation nicht finden.
Martin Thoma
2
Aus der Dokumentation: Das Ergebnis ist ein gültiger Python-Ausdruck . Ziel ist es, einen Python-Ausdruck zu erstellen, keine Endbenutzerdarstellungen. Gleiches gilt für oct()und hex().
Martijn Pieters
4
Weitere Alternativen: Wenn Sie gehen , um die Breite dynamisch zu machen, statt str.zfill()Sie nutzen könnten str.format()oder format()mit einem dynamischen zweiten Argumente: '{0:0{1}b}'.format(x, n)oder format(b, '0{}b'.format(n)).
Martijn Pieters
@MartijnPieters Wow, vielen Dank für diesen Beitrag! Ich wusste nicht, dass dies mit Format möglich ist. Ich denke jedoch, dass meine aktuelle Antwort mit zfillleichter zu lesen und zu verstehen ist als das dynamische zweite Argument, also werde ich das behalten.
Martin Thoma
38

Als Referenz:

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

Diese Funktion kann eine positive Ganzzahl konvertieren, die so groß wie 18446744073709551615ist und als Zeichenfolge dargestellt wird '1111111111111111111111111111111111111111111111111111111111111111'.

Es kann geändert werden, um eine viel größere Ganzzahl zu liefern, obwohl es möglicherweise nicht so praktisch ist wie "{0:b}".format()oder bin().

kctong529
quelle
@ GarethDavidson Welche Version ist das? Wenn dies explizit angegeben wird, kann dies beim Googeln in Zukunft von größerem Nutzen sein.
Wolf
Es war Version 2.7, denke ich. Ich bezweifle, dass es in 3.x funktionieren würde
Gareth Davidson
17

Eine einfache Möglichkeit hierfür ist die Verwendung des Zeichenfolgenformats (siehe diese Seite) .

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

Und wenn Sie eine feste Länge der Binärzeichenfolge haben möchten, können Sie Folgendes verwenden:

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

Wenn das Zweierkomplement erforderlich ist, kann die folgende Zeile verwendet werden:

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

Dabei ist n die Breite der Binärzeichenfolge.

Xiang
quelle
16

Dies ist für Python 3 und es behält die führenden Nullen!

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

Geben Sie hier die Bildbeschreibung ein

grepit
quelle
1
Ich schätze die einfache Antwort.
Reergymerej
14

Einzeiler mit Lambda :

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

Prüfung:

>>> binary(5)
'101'



BEARBEITEN :

aber dann :(

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

im Vergleich zu

t1 = time()
for i in range(1000000):
    '{0:b}'.format(i)
t2 = time()
print(t2 - t1)
# 0.68017411232
Aziz Alto
quelle
das gibt allerdings '' für 0 zurück. Wäre die normale Darstellung für 0 nicht '0'?
Dietbacon
Wenn Sie wollen sehen , dass 0 :), Sie ersetzen können ''mit '0', aber es wird eine führende 0 für eine beliebige Zahl hinzufügen.
Aziz Alto
11

Zusammenfassung der Alternativen:

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.

Zu den Mitwirkenden gehören John Fouhy , Tung Nguyen , mVChr und Martin Thoma . und Martijn Pieters.

BobStein-VisiBone
quelle
6
str.format()Nur einen Wert zu formatieren, ist übertrieben. Gehen Sie direkt zur format()Funktion : format(n, 'b'). Sie müssen den Platzhalter nicht analysieren und auf diese Weise einem Argument zuordnen.
Martijn Pieters
10

Da die vorhergehenden Antworten meistens format () verwendeten, ist hier eine F-String-Implementierung.

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

Ausgabe:

00111

Der Einfachheit halber finden Sie hier den Python-Dokument-Link für formatierte Zeichenfolgenliterale: https://docs.python.org/3/reference/lexical_analysis.html#f-strings .

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

Mit Numpy Pack / Unpackbits sind sie Ihre besten Freunde.

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)
Falle
quelle
Die Frage bezieht sich auf eine Zeichenfolgendarstellung . Trotzdem war dies genau das, wonach ich gesucht hatte, ohne vorher über einen String zu gehen! :)
Tom Hale
Das Dokument sagt: Entpackt Elemente eines uint8Arrays in ein binärwertiges Ausgabearray. So gut für Werte bis 255.
Tom Hale
5

Für diejenigen von uns, die vorzeichenbehaftete Ganzzahlen (Bereich -2 ** (Ziffern-1) in 2 ** (Ziffern-1) -1) in 2-Komplement-Binärzeichenfolgen konvertieren müssen, funktioniert dies:

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

Dies erzeugt:

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

Es sei denn, ich verstehe falsch, was Sie unter Binärzeichenfolge verstehen. Ich denke, das Modul, nach dem Sie suchen, ist struct

Van Gale
quelle
4

Noch eine Lösung mit einem anderen Algorithmus unter Verwendung bitweiser Operatoren.

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

Eine schnellere Version ohne Umkehrung der Zeichenfolge.

def int2bin(val):
   res=''
   while val>0:
       res = chr((val&1) + 0x30) + res
       val=val>>1    
   return res 
Reza Abtin
quelle
Die zweite Version ist definitiv nicht schneller, da Sie am Ende so etwas wie einen O (N ^ 2) -Algorithmus anstelle eines O (N) haben. Ich habe gesehen, wie solche Dinge eine Anwendung töteten (in Bezug auf die Leistung), weil der Entwickler dachte, ein zusätzlicher Durchgang am Ende sei langsamer als ein paar zusätzliche Dinge in der ersten Schleife. Einmal behoben, verringerte sich die Laufzeit von Tagen auf Sekunden.
Andreas Magnusson
4
def binary(decimal) :
    otherBase = ""
    while decimal != 0 :
        otherBase  =  str(decimal % 2) + otherBase
        decimal    //=  2
    return otherBase

print binary(10)

Ausgabe:

1010

Mukundan
quelle
4

Sie können so tun:

bin(10)[2:]

oder :

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

Hier ist der Code, den ich gerade implementiert habe. Dies ist keine Methode, aber Sie können sie als gebrauchsfertige Funktion verwenden !

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
quelle
3

Hier ist eine einfache Lösung mit der Funktion divmod (), die die Erinnerung und das Ergebnis einer Division ohne den Bruch zurückgibt.

def dectobin(number):
    bin = ''
    while (number >= 1):
        number, rem = divmod(number, 2)
        bin = bin + str(rem)
    return bin
user210021
quelle
Muss debuggt werden. Anruf dectobin(10)führte zu '0101'
Nate
3
n=input()
print(bin(n).replace("0b", ""))
dblaze
quelle
3

numpy.binary_repr(num, width=None)

Beispiele aus dem obigen Dokumentationslink:

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

Das Zweierkomplement wird zurückgegeben, wenn die Eingabenummer negativ ist und die Breite angegeben wird:

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

Etwas ähnliche Lösung

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
quelle
2

Hier ist noch eine andere Möglichkeit, normale Mathematik zu verwenden, keine Schleifen, nur Rekursion. (Trivialfall 0 gibt nichts zurück).

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']
Ergonaut
quelle
2

Rechner mit allen notwendigen Funktionen für DEC, BIN, HEX: (erstellt und getestet mit Python 3.5)

Sie können die eingegebenen Testnummern ändern und die konvertierten erhalten.

# 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
quelle
2

So berechnen Sie die Binärzahl von Zahlen:

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

So berechnen Sie die Hexa-Dezimalstelle einer Zahl :

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

Um alle binären Nr. Bis 16 zu berechnen ::

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

Zur Berechnung der Hexa-Dezimalzahl Nr. Bis 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
quelle
1

Wenn Sie bereit sind, "reines" Python aufzugeben, aber viel Feuerkraft zu gewinnen, gibt es hier Sage - Beispiel :

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

Sie werden feststellen, dass es als Zeichenfolge zurückgegeben wird. Wenn Sie es also als Zahl verwenden möchten, möchten Sie so etwas tun

sage: eval('0b'+b)
15
kcrisman
quelle
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
quelle
6
Vielleicht möchten Sie eine Erklärung zu dem hinzufügen, was Sie dort getan haben.
Artless
1

Ich habe eine Methode gefunden, die eine Matrixoperation verwendet, um Dezimalzahlen in Binärzahlen umzuwandeln.

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)

Eist eingegebene Dezimaldaten, Mist die binäre Reihenfolge. bindataEs werden Binärdaten ausgegeben, die in einem Format von 1 mal M Binärmatrix vorliegen.

Galle He
quelle
0

Hier ist ein einfacher Binär-Dezimal-Konverter, der sich kontinuierlich wiederholt

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

    print(convertedNumber)

print("")
Spencer Layland
quelle
Dies ist die umgekehrte Reihenfolge, die das OP wünscht. Sie suchen nach int zu binär. Sie geben binär an int.
Cecilia
0

Dies ist meine Antwort, es funktioniert gut ..!

def binary(value) :
    binary_value = ''
    while value !=1  :
        binary_value += str(value%2)
        value = value//2
    return '1'+binary_value[::-1]
Charunie Hansika AM
quelle
Was ist, wenn Sie den Wert übergeben 0? Bekommen binary(0)Sie zB das, was Sie erwarten?
Andreas Magnusson