Chuyển đổi thành nhị phân và giữ các số 0 đứng đầu trong Python


154

Tôi đang cố gắng chuyển đổi một số nguyên thành nhị phân bằng hàm bin () trong Python. Tuy nhiên, nó luôn loại bỏ các số 0 đứng đầu mà tôi thực sự cần, sao cho kết quả luôn là 8 bit:

Thí dụ:

bin(1) -> 0b1

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

Có cách nào để làm điều này?


Xem thêm: Python int để nhị phân? , đặc biệt là câu trả lời của tôi với biểu diễn n-bit. Không hoàn toàn giống nhau, nhưng tôi đã đến câu hỏi này để tìm kiếm câu trả lời của mình ...
Martin Thoma

Câu trả lời:


218

Sử dụng format()chức năng :

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

Các format()chức năng đơn giản là định dạng đầu vào sau khi Format ngôn ngữ kỹ thuật nhỏ . Các #làm cho định dạng bao gồm các 0btiền tố, và010 kích thước định dạng đầu ra để phù hợp với 10 ký tự chiều rộng, với 0đệm; 2 ký tự cho 0btiền tố, 8 ký tự còn lại cho các chữ số nhị phân.

Đây là tùy chọn nhỏ gọn và trực tiếp nhất.

Nếu bạn đang đặt kết quả trong một chuỗi lớn hơn, hãy sử dụng một chuỗi được định dạng bằng chữ (3.6+) hoặc sử dụng str.format()và đặt đối số thứ hai cho format()hàm sau dấu hai chấm của trình giữ chỗ {:..}:

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

Khi điều đó xảy ra, ngay cả khi chỉ định dạng một giá trị (vì vậy không đặt kết quả vào một chuỗi lớn hơn), sử dụng chuỗi ký tự được định dạng nhanh hơn so với sử dụng 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

Nhưng tôi chỉ sử dụng khi hiệu suất trong một vòng lặp chặt chẽ, như format(...) truyền đạt ý định tốt hơn.

Nếu bạn không muốn 0btiền tố, chỉ cần thả #và điều chỉnh độ dài của trường:

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

3
Chính xác những gì tôi đang tìm kiếm, định dạng này thực sự hữu ích cho tôi. Tôi đã bắt đầu học thao tác bit và tôi đang tìm kiếm định dạng bit cho các số trong Python. Tìm thấy cái này Cảm ơn bạn.
kratostoical 17/12/17

Hoạt động tốt. Có thể có một chút cồng kềnh mặc dù. format(192,'08b')+'.'+format(0,'08b')+'.'+format(2,'08b')+'.'+format(33,'08b') 11000000.00000000.00000010.00100001
tiếng nói

@ tjt263: Đó là lý do tại sao tôi tuyên bố rõ ràng rằng nếu bạn đặt kết quả trong một chuỗi lớn hơn, hãy sử dụng một chuỗi định dạng bằng chữ (3.6+) hoặc sử dụng str.format()và đặt đối số thứ hai cho hàm format () sau dấu hai chấm của trình giữ chỗ {:..}:
Martijn Pieters

1
@ tjt263: ví dụ: sử dụng f"{192:08b}.{0:08b}.{2:08b}.{33:08b}".
Martijn Pieters

Rất đẹp. Tôi sẽ không bao giờ biết đó là những gì bạn có nghĩa là từ giải thích một mình. Nhưng bây giờ tôi đã thấy ví dụ của bạn, có lẽ tôi sẽ không bao giờ quên nó. Chúc mừng.
tiếng nói

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

Xem: Đặc tả định dạng Ngôn ngữ nhỏ


Lưu ý đối với Python 2.6 trở lên, bạn không thể bỏ qua định danh đối số vị trí trước đó :, vì vậy hãy sử dụng

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

3
Không cần sử dụng str.format()ở đây khi nào format()sẽ làm. Bạn đang thiếu 0btiền tố.
Martijn Pieters

2
@MartijnPieters, str.formatlinh hoạt hơn format()vì nó sẽ cho phép bạn thực hiện nhiều biến số cùng một lúc. Tôi tiếp tục quên rằng formatchức năng thậm chí còn tồn tại. Phải thừa nhận rằng nó hoàn toàn đầy đủ trong trường hợp này.
Đánh dấu tiền chuộc

1
@MarkRansom: Chính xác, khi bạn chỉ sử dụng chỉ str.format()với một {}yếu tố, không có văn bản nào khác, bạn không sử dụng templating chuỗi, bạn đang định dạng một giá trị . Trong trường hợp đó chỉ cần sử dụng format(). :-)
Martijn Pieters

30

tôi đang dùng

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

sẽ in

'00000001'

9

Bạn có thể sử dụng ngôn ngữ định dạng chuỗi nhỏ:

def binary(num, pre='0b', length=8, spacer=0):
    return '{0}{{:{1}>{2}}}'.format(pre, spacer, length).format(bin(num)[2:])

Bản giới thiệu:

print binary(1)

Đầu ra:

'0b00000001'

EDIT: dựa trên ý tưởng của @Martijn Pieters

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

2
Ngôn ngữ định dạng tương tự có thể được sử dụng để bao gồm tiền tố cho bạn. Sử dụng #. Ngoài ra còn có format(), giúp bạn tiết kiệm được một mẫu chuỗi đầy đủ.
Martijn Pieters

2

Khi sử dụng Python >= 3.6, cách sạch nhất là sử dụng chuỗi f với định dạng chuỗi :

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

Giải trình:

  • var biến để định dạng
  • : tất cả mọi thứ sau đây là định dạng định dạng
  • #sử dụng hình thức thay thế (thêm 0btiền tố)
  • 0 pad với số không
  • 10đệm đến tổng chiều dài 10 (bao gồm 2 ký tự cho 0b)
  • b sử dụng biểu diễn nhị phân cho số

Không, nó không phải là sạch nhất, trừ khi bạn làm nhiều hơn với chuỗi hơn là chỉ một trình giữ chỗ . Nếu không thì format(var, "#010b")truyền đạt ý định tốt hơn nhiều. Tuy nhiên, đây là lựa chọn nhanh nhất. Nhưng bạn biết điều đó rồi, đúng rồi, vì tôi đã trình bày tất cả những gì bạn đăng trong câu trả lời của tôi.
Martijn Pieters

1

Đôi khi bạn chỉ muốn một lớp lót đơn giản:

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

Con trăn 3


1
Lưu ý rằng [ ]không cần thiết - join()chấp nhận biểu thức trình tạo. ''.join('{0:08b}'.format(ord(x)) for x in input)
Christoph Burschka

@ChristophBurschka lưu ý rằng vì str.join()cần thực hiện hai lần vượt qua, đầu vào trình tạo trước tiên được chuyển đổi thành danh sách trước khi tham gia. Điều này gây ra một chút phí cho hiệu suất và thực sự ở đây tốt hơn để vượt qua trong việc hiểu danh sách hơn là biểu thức của trình tạo. Đó là một nếu họ ngoại lệ cho quy tắc.
Martijn Pieters

-1

Bạn có thể sử dụng một cái gì đó như thế này

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

2
Vui lòng ít nhất sử dụng khối mã cho đoạn mã của bạn. Và nếu bạn thực sự muốn nó là một câu trả lời tốt, thì cũng thêm một số ý kiến ​​về lý do tại sao giải pháp này đang giải quyết câu hỏi OP.
β.εη

Bạn không cần sử dụng kiểu định dạng chuỗi khác nhau chỉ để thêm chiều rộng thay đổi. Chỉ cần thêm một trình giữ chỗ khác:"{:0{l}b}".format(num, l=length)
Martijn Pieters

-1

bạn có thể sử dụng phương thức chuỗi rjust của cú pháp python: string.rjust (length, fillchar) fillchar là tùy chọn

và cho câu hỏi của bạn, bạn viết như thế này

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

vì vậy nó sẽ là '0b00000001'


Có lỗi cú pháp. Nhưng quan trọng hơn, nó hoàn toàn không trả lời câu hỏi, mà là về việc chuyển đổi một intbiểu diễn nhị phân văn bản của nó; bạn thậm chí không bắt đầu với một int.
Thierry Lathuille

-3

Bạn có thể sử dụng zfill:

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

in:

01
10
100

Tôi thích giải pháp này, vì nó không chỉ giúp khi xuất số, mà khi bạn cần gán nó cho một biến ... ví dụ: x = str (datetime.date.today (). Tháng) .zfill (2) sẽ trả về x là '02' cho tháng của feb.


1
vấn đề với zfill là nó xử lý chuỗi nhị phân như một chuỗi và thêm các số 0 trước chỉ báo 'b' nhị phân ... ví dụ bin(14) cho `'0b1110'` và bin(14).zfill(8) cho `'000b1110'` không `'0b00001110'` đó là những gì mong muốn
Shaun
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.