Python int ikili dize?


530

Bir Tamsayıyı (veya Uzun) Python'daki bir ikili dizeye dönüştürmek için hazır Python yöntemleri var mı?

Google'da sayısız dec2bin () işlevi var ... Ama yerleşik bir işlev / kütüphane kullanabileceğimi umuyordum.


Tersi bir gezi için, saf bir dize işleme algoritması için, bkz bu .
CopyPasteIt

Yanıtlar:


750

Python'un dize biçimi yöntemi bir biçim spec alabilir.

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

Python 2 için özellik belgelerini biçimlendirme

Python 3 için özellik belgelerini biçimlendirme


86
str.format()sadece bir değeri biçimlendirmek aşırıdır. Düz git format()fonksiyonu : format(n, 'b'). Yer tutucuyu ayrıştırıp bir argümanla eşleştirmeye, değer biçimlendirme işleminin kendisi için doğrudan gitmeye gerek yoktur. Yalnızca str.format()biçimlendirilmiş sonucu daha uzun bir dizeye yerleştirmeniz gerekiyorsa kullanın (örneğin, şablon olarak kullanın).
Martijn Pieters

29
@mike: Veya biçimlendirme belirtimini kullanın. 0Satır başını biçimlendirme dizesine ekleyen basamak sayısını ekleyin : format(10, '016b')baştaki sıfırlarla 16 basamağa kadar biçimler.
Martijn Pieters

Bu durumda 0in "{0:b}"düşebilir hayır? Demek istediğim, sadece bir sayının biçimlendirilmesi durumunda koymak doğru "{:b}", değil mi?
tomasyany

1
tipik olarak 4/8 / ... bit gösterimi kullanılır:"{:08b}".format(37)
Maytap

2
f "{37: b}", Python3.7 veya sonraki sürümlerinde.
DA

471

Şuna bin()eşdeğer olarak arıyorsanız:hex() , python 2.6'ya eklenmiştir.

Misal:

>>> bin(10)
'0b1010'

66
Ayrıca str(bin(i))[2:](1000000ops için 0,379s) yapmanın daha hızlı olduğunu "{0:b}".format(i)(1000000ops için 0,721s) unutmayın
mVChr

64
Eğer birisi ASCII ikili temsile sayıları dönüştürüyorsa, hızın önemli olmadığını umuyorum.
Nick T

29
@mVChr: str.format()yanlış bir araç zaten, format(i, 'b')bunun yerine kullanabilirsiniz . Ancak bunun aynı zamanda dolgu ve hizalama seçenekleri sunduğunu da dikkate alın; format(i, '016b')16 bit sıfır dolgulu bir ikili sayı olarak biçimlendirmek için. Aynı işlemi yapmak için bin()bir str.zfill()arama eklemeniz bin(i)[2:].zfill(16)gerekir : (aramanıza gerek yok str()!). format()'nin okunabilirliği ve esnekliği (dinamik biçimlendirme çok daha zordur bin()) büyük ödünleşmedir, gerekmedikçe performans için optimize etmeyin, o zamana kadar sürdürülebilirlik için optimize edin.
Martijn Pieters

[2:] ne anlama geliyor?
zero_cool

4
Tabii ki, python 3.6+ ile artık kullanabilirsiniz f"{37:b}".
Luke Davis

63

Python aslında yapar zaten bunun için yerleşik bir şey var gibi işlemleri yapmak yeteneği '{0:b}'.format(42)size (a dizede) bit deseni sağlayacak bütün 42veya 101010.


Daha genel bir felsefe için, hiçbir dil veya kütüphane kullanıcı tabanına istediği her şeyi vermez . Tam olarak ihtiyacınız olanı sağlamayan bir ortamda çalışıyorsanız, aynı şeyi asla iki kez yazmak zorunda kalmamanız için geliştirdiğiniz kod parçacıklarını toplamalısınız. Örneğin, sözde kod:

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

ikili dizginizi ondalık değere dayalı olarak oluşturur. Ancak, bunu yapmanın en etkili yolu olmayabilecek genel bir sahte kod parçası olduğunu unutmayın, teklif ettiğiniz yinelemelerle, çok fazla fark yaratmayacaktır. Gerçekten sadece bunun nasıl yapılabileceğine dair bir rehber niteliğindedir.

Genel fikir, kodu (tercih sırasına göre) kullanmaktır:

  • dil veya yerleşik kütüphaneler.
  • uygun lisanslara sahip üçüncü taraf kütüphaneleri.
  • kendi koleksiyonunuz.
  • yazmanız gereken yeni bir şey (ve daha sonra kullanmak üzere kendi koleksiyonunuza kaydetmeniz).

1
Bu cevapta bazı iyi tavsiyeler. Sadece kod çok gereksiz yavaş kötü. O (N) 'nun yapacağı bir O (N ^ 2) algo önerirsiniz. Sorunlu kısmı s = "1" + sve s = "0" + sçizgilerindedir. Her biri s'nin gereksiz bir kopyasını oluşturur. Dizeyi geri döndürmeden hemen önce tersine çevirmelisiniz.
Andreas Magnusson

@Andreas, kullanmak için önerdiğim , '{0:b}'.format(42)yavaş yöntem sadece kullanılan gerçek dile bağlı olarak O (n ^ 2) olabilir veya olmayabilir, jenerik olarak nasıl yapılacağının bir örneğiydi. Python ideal bir sahte kod dili olduğu için sadece Python'a benziyor, bu yüzden bunu netleştirmek için değiştireceğim.
paxdiablo

Aslında bir dize türü s = "1" + solduğunda O (N) olmayan oldukça ezoterik bir dil olurdu s. Belki tüm dizelerin geriye doğru saklandığı bir dil veya her karakter bağlı bir listedeki bir düğümdür? Herhangi bir tipik dil için bir dize temelde karakter dizisidir. Bu durumda bir dize önekinin eklenmesi için bir kopyasının hazırlanması gerekir, karakteri diğer karakterlerin önüne nasıl koyacaksınız?
Andreas Magnusson

Ben kolayca dize bu blok içinde haklı olduğu bir bellek bloğu ve onun başlangıç ​​karakteri bir mahsup oluşan bir dize türü düşünebilirsiniz. Bir karaktere önek eklemek için, ofseti azaltmanız ve karakteri orada saklamanız yeterlidir. Evet, bu ezoterik olurdu , ancak özellikle birkaç düzine bit / yinelemeye sahip olmayacağınız için , biraz sahte kod içeren olası gerçek dünya sorunları hakkında tartışmak benim için çok mantıklı değil. Veri boyutunuz küçükse, çok kötü huylu kabarcık sıralaması yeterlidir :-) Her durumda, verimlilik hakkında bir not ekleyeceğim.
paxdiablo

Elbette, verimlilik önemliyse, başlangıçta muhtemelen python'u seçmezsiniz. Yine de benim tecrübelerime göre, sık sık O (N²) algo kullanılarak yazılan ve küçük bir veri seti ile test edilen kod çok daha büyük bir veri seti ile birlikte kullanılır çünkü "çalışıyor gibi görünüyor". Sonra aniden sabit zaman çalıştırmak sadece birkaç saniye sürebilir çalıştırmak için kod alır. O (N²) algos sinsi çünkü bir süre çalışıyor gibi görünüyor ama veri ölçeklendirdiklerinde onlar yok ve o zaman onları yazan adam bıraktı ve kimse neden şeylerin sonsuza kadar sürdüğünü bilmiyor.
Andreas Magnusson

41

0b öneki olmayan bir metin temsili istiyorsanız, bunu kullanabilirsiniz:

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

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

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

Bir n-bit gösterim istediğinizde:

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

Alternatif olarak, bir işleve sahip olmayı tercih ediyorsanız:

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
Veya sadece kullanın format(integer, 'b'). bin()özellikle üretmeyi amaçlayan bir ayıklama aracı, ikili sayı değişmez sözdizimini Python , format()üretmek belirli biçimlerde kastedilmektedir.
Martijn Pieters

1
@MartijnPieters Bahsettiğiniz için çok teşekkür ederim. Çözümümü ayarladım. Bunun bin()Python ikili tamsayı değişmez sözdizimini üretmeyi amaçlayan bir hata ayıklama aracı olduğunu nereden biliyorsunuz ? Bunu belgelerde bulamadım.
Martin Thoma

2
Belgelerden: Sonuç geçerli bir Python ifadesidir . Amacı, son kullanıcı temsili üretmek değil, bir Python ifadesi üretmektir. Aynısı oct()ve için de geçerlidir hex().
Martijn Pieters

4
Daha alternatifleri: yerine, genişlik dinamik hale getirmek için yapacaksanız str.zfill()size kullanabilirsiniz str.format()ya format(): Dinamik ikinci argüman ile '{0:0{1}b}'.format(x, n)veya format(b, '0{}b'.format(n)).
Martijn Pieters

@MartijnPieters Vay be, bu girdi için çok teşekkür ederim! Bunun formatla mümkün olduğunu bilmiyordum. Bununla birlikte, şu anki cevabımın zfilldinamik ikinci argümandan daha kolay okunması ve anlaşılması olduğunu düşünüyorum , bu yüzden saklayacağım.
Martin Thoma

38

Referans olarak:

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

Bu işlev, 18446744073709551615dize olarak temsil edilen kadar büyük bir pozitif tamsayıyı dönüştürebilir'1111111111111111111111111111111111111111111111111111111111111111' .

Çok daha büyük bir tamsayı sunmak için değiştirilebilir, ancak "{0:b}".format()veya kadar kullanışlı olmayabilir bin().


@GarethDavidson bu hangi sürüm? Bunu açıkça belirtmek, googling yaparken gelecekte daha fazla kullanım sağlayabilir.
Wolf

Sanırım 2.7 sürümüydi. 3.x'te işe yarayacağından şüpheliyim
Gareth Davidson

17

Bunu yapmanın basit bir yolu dize biçimini kullanmaktır, bu sayfaya bakın .

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

Ve ikili dizenin sabit bir uzunluğuna sahip olmak istiyorsanız, bunu kullanabilirsiniz:

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

İkisinin tamamlayıcısı gerekiyorsa, aşağıdaki satır kullanılabilir:

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

burada n, ikili dizginin genişliğidir.



14

ile bir liner lambda :

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

Ölçek:

>>> binary(5)
'101'



DÜZENLE :

ama sonra :(

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

kıyasla

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

0 için '' döndürür. 0 için normal gösterim '0' olmaz mı?
dietbacon

Eğer bunu 0 görmek istiyorsanız :) ''ile değiştirebilirsiniz '0', ancak herhangi bir sayı için baştaki 0 ​​ekleyecektir.
Aziz Alto

11

Alternatiflerin özeti:

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.

Katkıda bulunanlar arasında John Fouhy , Tung Nguyen , mVChr , Martin Thoma sayılabilir . ve Martijn Pieters.


6
str.format()sadece bir değeri biçimlendirmek aşırıdır. Düz git format()fonksiyonu: format(n, 'b'). Yer tutucuyu ayrıştırmaya ve bu şekilde bir argümanla eşleştirmeye gerek yoktur.
Martijn Pieters



5

Numpy pack / unpackbits kullanarak en iyi arkadaşlarınızdır.

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)

Soru, bir dize temsiliyle ilgilidir. Yine de, bu ilk önce ip üzerinden gitmeden aradığım şey oldu! :)
Tom Hale

Doco diyor ki: a paketten çıkarır elemanları uint8ikili değerli çıkış diziye diziye.
Tom Hale

5

İşaretli tam sayıları (aralık -2 ** (basamak-1) - 2 ** (basamak-1) -1) 2'nin tamamlayıcı ikili dizelerine dönüştürmek zorunda kalanlarımız için:

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

Bu şunu üretir:

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


4

Bitsel operatörler kullanarak başka bir algoritma ile başka bir çözüm.

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

Dizeyi tersine çevirmeden daha hızlı bir sürüm.

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

O (N) yerine O (N ^ 2) algoritması gibi bir şeyle karşılaştığınızda ikinci sürüm kesinlikle daha hızlı değildir. Bunun gibi bir uygulamayı (performans açısından) öldürdüğünü gördüm çünkü geliştirici sonunda ekstra bir geçiş yapmanın ilk döngüde bazı ekstra şeyler yapmaktan daha yavaş olduğunu düşündü. Sabitlendiğinde, çalışma süresi günlerden saniyelere düşürüldü.
Andreas Magnusson

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

print binary(10)

çıktı:

1010


4

böyle yapabilirsin:

bin(10)[2:]

veya:

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

bin (n) .replace ("0b", "")
sanner küçük

3

İşte yeni uyguladığım kod. Bu bir yöntem değildir, ancak kullanıma hazır bir işlev olarak kullanabilirsiniz !

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

Burada, hatırlatıcıyı ve kesirsiz bir bölünmenin sonucunu döndüren divmod () işlevini kullanan basit bir çözüm var.

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

Hata ayıklama gerekiyor. Arama dectobin(10)sonucu '0101'
Nate


3

numpy.binary_repr(num, width=None)

Yukarıdaki belge bağlantısından örnekler:

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

Giriş numarası negatif olduğunda ve genişlik belirtildiğinde ikisinin tamamlayıcısı döndürülür:

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

2

Biraz benzer bir çözüm

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

İşte düzenli matematik kullanmanın başka bir yolu, döngüler yok, sadece özyineleme. (Önemsiz durum 0 hiçbir şey döndürmez).

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

DEC, BIN, HEX için tüm gerekli işlevlere sahip hesap makinesi: (Python 3.5 ile yapılmış ve test edilmiştir)

Giriş test numaralarını değiştirebilir ve dönüştürülmüş olanları alabilirsiniz.

# 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

Sayıların ikili sayılarını hesaplamak için:

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

Bir sayının Hexa ondalık değerini hesaplamak için :

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

Tüm ikili no'ları 16'ya kadar hesaplamak için ::

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

Onaltılık sayıyı 17'ye kadar hesaplamak için

 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

"Saf" Python'dan vazgeçmek istiyor, ancak çok fazla ateş gücü elde etmek istiyorsanız , Sage var - burada örnek :

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

Bir dize olarak döndüğünü fark edeceksiniz, bu yüzden bir sayı olarak kullanmak için aşağıdaki gibi bir şey yapmak istersiniz

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
Orada yaptıklarınıza bir açıklama eklemek isteyebilirsiniz.
Artless

1

Ondalık ikiliye dönüştürmek için matris işlemi kullanarak bir yöntem buldum.

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)

Eondalık veri girişi M, ikili emirdir. bindataM ikili matrisi tarafından 1 biçiminde olan çıktı ikili verileridir.


0

İşte sürekli döngü yapan basit bir ikili ila ondalık dönüştürücü

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

    print(convertedNumber)

print("")

Bu OP'nin istediklerinin tersi sıra. Onlar int ikili ikili arıyorlar. İnt.
Cecilia

0

Bu benim cevabım iyi çalışıyor ..!

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

Ya değeri geçerseniz 0? Örneğin binary(0), beklediğiniz şeyi alacak mısınız?
Andreas Magnusson
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.