Konversikan ke biner dan pertahankan angka nol di Python

154

Saya mencoba untuk mengkonversi integer ke biner menggunakan fungsi bin () dengan Python. Namun, itu selalu menghilangkan nol terkemuka, yang sebenarnya saya butuhkan, sehingga hasilnya selalu 8-bit:

Contoh:

bin(1) -> 0b1

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

Apakah ada cara untuk melakukan ini?

Niels Sønderbæk
sumber
Lihat juga: Python int ke biner? , terutama jawaban saya dengan representasi n-bit. Tidak persis sama, tetapi saya sampai pada pertanyaan ini mencari jawaban saya ...
Martin Thoma

Jawaban:

220

Gunakan format()fungsinya :

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

The format()Fungsi hanya format input mengikuti Format bahasa Keterangan Mini . The #membuat format termasuk 0bawalan, dan 010ukuran format output untuk cocok 10 karakter lebar, dengan 0bantalan; 2 karakter untuk 0bawalan, 8 lainnya untuk digit biner.

Ini adalah opsi paling ringkas dan langsung.

Jika Anda meletakkan hasilnya dalam string yang lebih besar, gunakan string string yang diformat (3,6+) atau gunakan str.format()dan letakkan argumen kedua untuk format()fungsi setelah titik dua dari placeholder {:..}:

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

Seperti yang terjadi, bahkan untuk hanya memformat nilai tunggal (jadi tanpa meletakkan hasilnya dalam string yang lebih besar), menggunakan string literal yang diformat lebih cepat daripada menggunakan 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

Tapi saya akan menggunakannya hanya jika kinerja dalam loop ketat penting, karena format(...)mengkomunikasikan maksud lebih baik.

Jika Anda tidak ingin 0bawalan, cukup jatuhkan #dan sesuaikan panjang bidang:

>>> format(14, '08b')
'00001110'
Martijn Pieters
sumber
3
Persis apa yang saya cari, format ini sangat membantu saya. Saya sudah mulai belajar manipulasi bit dan saya googling untuk memformat bit untuk angka dengan Python. Menemukan ini Terima kasih.
kratostoical
Bagus sekali. Bisa jadi agak tebal sekalipun. format(192,'08b')+'.'+format(0,'08b')+'.'+format(2,'08b')+'.'+format(33,'08b') 11000000.00000000.00000010.00100001
Suara
@ tjt263: Itulah sebabnya saya secara eksplisit menyatakan bahwa Jika Anda meletakkan hasilnya dalam string yang lebih besar, gunakan string string yang diformat (3,6+) atau gunakan str.format()dan letakkan argumen kedua untuk fungsi format () setelah tanda titik dua {:..}:
Martijn Pieters
1
@ tjt263: mis f"{192:08b}.{0:08b}.{2:08b}.{33:08b}". gunakan .
Martijn Pieters
Sangat bagus. Saya tidak akan pernah tahu itu yang Anda maksud dari penjelasan saja. Tetapi sekarang saya telah melihat teladan Anda, saya mungkin tidak akan pernah melupakannya. Bersulang.
Suara
115
>>> '{:08b}'.format(1)
'00000001'

Lihat: Format Spesifikasi Mini-Bahasa


Catatan untuk Python 2.6 atau lebih lama, Anda tidak bisa menghilangkan pengidentifikasi argumen posisi sebelumnya :, jadi gunakan

>>> '{0:08b}'.format(1)
'00000001'      
bwbrowning
sumber
3
Tidak perlu menggunakan di str.format()sini kapan format()akan dilakukan. Anda tidak memiliki 0bawalan.
Martijn Pieters
2
@ MartijnPieters, str.formatlebih fleksibel daripada format()karena itu akan memungkinkan Anda untuk melakukan beberapa variabel sekaligus. Saya terus lupa bahwa formatfungsinya bahkan ada. Memang ini sangat memadai dalam hal ini.
Mark Ransom
1
@ Markarkom: Tepat, ketika Anda hanya menggunakan hanya str.format()dengan satu {}elemen, tidak ada teks lain, Anda tidak menggunakan string templating, Anda memformat satu nilai . Dalam hal ini gunakan saja format(). :-)
Martijn Pieters
30

saya menggunakan

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

akan dicetak

'00000001'
rekinyz
sumber
9

Anda dapat menggunakan bahasa mini pemformatan string:

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)

Keluaran:

'0b00000001'

EDIT: berdasarkan ide @Martijn Pieters

def binary(num, length=8):
    return format(num, '#0{}b'.format(length + 2))
Peter Varo
sumber
2
Bahasa pemformatan yang sama dapat digunakan untuk menyertakan awalan untuk Anda. Gunakan #. Ada juga format(), yang menghemat Anda harus melakukan template string penuh.
Martijn Pieters
2

Saat menggunakan Python >= 3.6, cara terbersih adalah menggunakan f-string dengan pemformatan string :

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

Penjelasan:

  • var variabel ke format
  • : semuanya setelah ini adalah penentu format
  • #gunakan formulir alternatif (tambahkan 0bawalan)
  • 0 pad dengan nol
  • 10pad untuk total panjang 10 (ini termasuk 2 karakter untuk 0b)
  • b gunakan representasi biner untuk nomor tersebut
ruohola
sumber
Tidak, ini bukan yang terbersih, kecuali Anda melakukan lebih banyak dengan string daripada hanya satu penampung tunggal . Kalau tidak, format(var, "#010b")berkomunikasi maksud jauh lebih baik. Namun, ini adalah opsi tercepat. Tapi Anda sudah tahu itu, benar, karena saya sudah membahas semua yang Anda posting dalam jawaban saya.
Martijn Pieters
1

Terkadang Anda hanya ingin satu liner sederhana:

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

Python 3

Menandai
sumber
1
Perhatikan bahwa yang [ ]seharusnya tidak diperlukan - join()menerima ekspresi generator. ''.join('{0:08b}'.format(ord(x)) for x in input)
Christoph Burschka
@ChristophBurschka perhatikan bahwa karena str.join()perlu membuat dua lintasan, input generator pertama dikonversi ke daftar sebelum bergabung. Ini membutuhkan sedikit pengorbanan pada kinerja dan melakukannya sebenarnya lebih baik di sini untuk lulus dalam pemahaman daftar daripada ekspresi generator. Itu satu jika mereka pengecualian terhadap aturan.
Martijn Pieters
-1

Anda dapat menggunakan sesuatu seperti ini

("{:0%db}"%length).format(num)
Adam
sumber
2
Harap setidaknya gunakan blok kode untuk cuplikan kode Anda. Dan jika Anda benar-benar menginginkannya menjadi jawaban yang baik, maka tambahkan juga komentar tentang mengapa solusi ini menyelesaikan pertanyaan OP.
β.εηοιτ.βε
Anda tidak perlu menggunakan gaya pemformatan string yang berbeda hanya untuk menambahkan lebar variabel. Tambahkan saja placeholder lain:"{:0{l}b}".format(num, l=length)
Martijn Pieters
-1

Anda dapat menggunakan metode string rjust dari sintaks python: string.rjust (length, fillchar) fillchar adalah opsional

dan untuk Pertanyaan Anda, Anda dapat menulis seperti ini

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

jadi itu akan menjadi '0b00000001'

Jaydeep Mahajan
sumber
Ada kesalahan sintaksis. Tetapi yang lebih penting, itu tidak menjawab pertanyaan sama sekali, yaitu tentang mengubah suatu intke representasi biner teksnya; Anda bahkan tidak memulai dengan int.
Thierry Lathuille
-3

Anda dapat menggunakan zfill:

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

cetakan:

01
10
100

Saya suka solusi ini, karena tidak hanya membantu saat mengeluarkan nomor, tetapi ketika Anda perlu menetapkannya ke variabel ... misalnya - x = str (datetime.date.today (). Bulan) .zfill (2) akan return x sebagai '02' untuk bulan Februari.

Anshul Garg
sumber
1
masalah dengan zfill adalah memperlakukan string biner seperti string dan menambahkan nol sebelum indikator 'b' biner ... misalnya bin(14) memberikan `'0b1110'` dan bin(14).zfill(8) memberikan `'000b1110'` bukan `'0b00001110'` yang merupakan apa yang diinginkan
Shaun