İkiliye dönüştür ve Python'da baştaki sıfırları tut


161

Python'da bin () işlevini kullanarak bir tamsayıyı ikiliye dönüştürmeye çalışıyorum. Ancak, aslında ihtiyacım olan baştaki sıfırları her zaman kaldırır, böylece sonuç her zaman 8-bit olur:

Misal:

bin(1) -> 0b1

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

Bunu yapmanın bir yolu var mı?


Ayrıca bkz: Python int to binary? , özellikle n-bit gösterimi ile ilgili cevabım . Tam olarak aynı, ama ben ... cevabımı arama bu soruya geldi
Martin Thoma

Yanıtlar:


229

Şu format()işlevi kullanın :

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

format()Fonksiyon sadece aşağıdaki giriş biçimleri Biçim Şartname Mini dili . Bu #, biçimin 0böneki içermesini ve 010boyut biçimlerinin çıktının 0dolgu ile 10 karakter genişliğe sığmasını sağlar ; 0bÖnek için 2 karakter , ikili rakamlar için diğer 8 karakter .

Bu en kompakt ve doğrudan seçenektir.

Sonucu daha büyük bir dizeye koyuyorsanız, biçimlendirilmiş bir dize hazır bilgisi (3.6+) kullanın veya işlev str.format()için ikinci bağımsız değişkeni format()yer tutucunun kolonundan sonra koyun ve koyun {:..}:

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

Olduğu gibi, yalnızca tek bir değeri biçimlendirmek için bile (yani sonucu daha büyük bir dizeye koymadan), biçimlendirilmiş bir dize değişmezi kullanmak, kullanmaktan daha hızlıdır 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

Ancak bunu yalnızca dar bir döngüdeki performans önemliyse format(...)ve amacı daha iyi ilettiği için kullanırım.

0bÖneki istemediyseniz , basitçe bırakın #ve alanın uzunluğunu ayarlayın:

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

3
Tam olarak aradığım şey, bu biçimlendirme bana gerçekten yardımcı oldu. Bit manipülasyonunu öğrenmeye başladım ve Python'daki sayılar için bit biçimlendirmesi için googling yapıyordum. Bunu buldum. Teşekkür ederim.
kratostoical

Güzel çalışıyor. Yine de biraz hantal olabilir. format(192,'08b')+'.'+format(0,'08b')+'.'+format(2,'08b')+'.'+format(33,'08b') 11000000.00000000.00000010.00100001
dile

@ tjt263: Bu nedenle , sonucu daha büyük bir dizeye koyuyorsanız, biçimlendirilmiş bir dize hazır bilgisi (3.6+) kullanın veya str.format()format () işlevi için ikinci bağımsız değişkeni yer tutucunun iki nokta üstüstünden sonra koyun ve koyun {:..}:
Martijn Pieters

1
@ tjt263: ör. kullanın f"{192:08b}.{0:08b}.{2:08b}.{33:08b}".
Martijn Pieters

Çok hoş. Sadece açıklamadan kastettiğin şeyin bu olduğunu asla bilemezdim. Ama şimdi örneğinizi gördüm, muhtemelen asla unutmayacağım. Şerefe.
sesler

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

Bakınız: Biçim Belirtimi Mini Dil


Python 2.6 veya daha eski sürümler için, konumsal bağımsız değişken tanımlayıcısını daha önce ihmal edemezsiniz :, bu nedenle şunu kullanın:

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

3
str.format()Ne zaman format()yapacağımı burada kullanmaya gerek yok. 0bÖneki eksik .
Martijn Pieters

2
@MartijnPieters, str.formataynı format()anda birden fazla değişken yapmanıza izin vereceğinden daha esnektir . formatİşlevin var olduğunu bile unutuyorum . Kuşkusuz bu durumda tamamen yeterli.
Mark Ransom

1
@MarkRansom: Yalnızca kullanırken Kesinlikle, str.format()sadece bir ile {}, sen edilir elemanı, başka hiçbir metin değil dize çiftleşmiş kullanarak, biçimlendirme vardır bir değer . Bu durumda sadece kullanın format(). :-)
Martijn Pieters

30

Ben kullanıyorum

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

yazdıracak

'00000001'

9

Dize formatlama mini dilini kullanabilirsiniz:

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)

Çıktı:

'0b00000001'

DÜZENLEME: @Martijn Pieters fikrine göre

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

2
Öneki sizin yerinize eklemek için aynı biçimlendirme dili kullanılabilir. Kullanın #. Ayrıca, format()sizi tam bir dize şablonu yapmak zorunda bırakan da vardır .
Martijn Pieters

2

Python kullanırken >= 3.6, en temiz yolu kullanmaktır f-dizeleri ile dize biçimlendirme :

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

Açıklama:

  • var biçimlendirilecek değişken
  • : bundan sonraki her şey biçim belirleyicidir
  • #alternatif formu kullanın ( 0böneki ekler )
  • 0 sıfırlarla doldurmak
  • 10toplam uzunluğu 10'a kadar doldurun (bu, için 2 karakter içerir 0b)
  • b sayı için ikili gösterimi kullanın

Hayır, dizeyle tek bir yer tutucudan daha fazlasını yapmadığınız sürece bu en temiz değildir . Aksi takdirde, niyeti çok daha iyi format(var, "#010b")iletir . Bununla birlikte, en hızlı seçenektir. Ama bunu zaten biliyorsun, çünkü cevabımda gönderdiklerinin hepsini zaten kapsıyorum .
Martijn Pieters

1

Bazen basit bir tek satırlık istersiniz:

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

Python 3


1
Bunun [ ]gerekli olmadığına dikkat edin - join()bir üretici ifadesini kabul eder. ''.join('{0:08b}'.format(ord(x)) for x in input)
Christoph Burschka

@ChristophBurschka str.join(), iki geçiş yapılması gerektiğinden, bir jeneratör girdisinin katılmadan önce bir listeye dönüştürüldüğünü unutmayın. Bu performansı üzerinde geçiş ücreti biraz alır ve aslında yapmak daha iyi bir liste anlama yerine bir jeneratör ifadede geçmesine burada. Kuralın istisnaları varsa bir.
Martijn Pieters

-1

Bunun gibi bir şey kullanabilirsin

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

2
Lütfen kod pasajınız için en azından kod bloğu kullanın. Ve eğer gerçekten iyi bir cevap olmasını istiyorsanız, o zaman bu çözümün neden OP sorusunu çözdüğüne dair bazı yorumlar da ekleyin.
β.εηοιτ.βε

Değişken genişlik eklemek için farklı bir dize biçimlendirme stili kullanmanıza gerek yoktur. Sadece başka bir yer tutucu ekleyin:"{:0{l}b}".format(num, l=length)
Martijn Pieters

-2

python sözdiziminin rjust string yöntemini kullanabilirsiniz: string.rjust (length, fillchar) fillchar isteğe bağlıdır

ve sorunuz için böyle yazarsınız

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

yani '0b00000001' olacak


Bir sözdizimi hatası var. Ama daha da önemlisi, inta'yı metinsel ikili temsiline dönüştürmekle ilgili olan soruyu hiç cevaplamıyor ; bir ile başlamıyorsun bile int.
Thierry Lathuille

-3

Zfill'i kullanabilirsiniz:

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

baskılar:

01
10
100

Bu çözümü beğendim, çünkü sadece sayıyı verirken değil, aynı zamanda onu bir değişkene atamanız gerektiğinde ... örneğin - x = str (datetime.date.today (). Month) .zfill (2) x'i şubat ayı için "02" olarak döndür.


1
zfill ile ilgili sorun, ikili dizgeyi bir dizge gibi ele alıp ikili 'b' göstergesinden önce sıfırları bin(14) eklemesidir ... örn. "'0b1110' ' bin(14).zfill(8) verir ve "' 000b1110 "değil" '0b00001110' 'verir ki bu istenen şeydir
Shaun
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.