Python int đến chuỗi nhị phân?


530

Có phương thức Python đóng hộp nào để chuyển đổi một Integer (hoặc Long) thành một chuỗi nhị phân trong Python không?

Có vô số hàm dec2bin () trên Google ... Nhưng tôi đã hy vọng mình có thể sử dụng hàm / thư viện tích hợp.


Đối với ngược lại, đối với một thuật toán xử lý chuỗi thuần túy, hãy xem điều này .
CopyPasteIt

Câu trả lời:


750

Phương pháp định dạng chuỗi của Python có thể lấy thông số định dạng.

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

Định dạng tài liệu đặc tả cho Python 2

Định dạng tài liệu đặc tả cho Python 3


86
str.format()chỉ để định dạng một giá trị là quá mức cần thiết. Đi thẳng đến format()chức năng : format(n, 'b'). Không cần phải phân tích trình giữ chỗ và khớp nó với một đối số, đi thẳng vào chính hoạt động định dạng giá trị. Chỉ sử dụng str.format()nếu bạn cần đặt kết quả được định dạng trong một chuỗi dài hơn (ví dụ: sử dụng nó làm mẫu).
Martijn Pieters

29
@mike: Hoặc sử dụng đặc tả định dạng. Thêm số chữ số dẫn 0đến chuỗi định dạng: format(10, '016b')định dạng thành 16 chữ số có số 0 đứng đầu.
Martijn Pieters

Trong trường hợp này 0trong "{0:b}"có thể được giảm không? Ý tôi là, trong trường hợp chỉ có một số được định dạng, việc đặt chính xác là đúng "{:b}", phải không?
tomasyany

1
thông thường người ta sẽ sử dụng biểu diễn 4/8 / ... bit:"{:08b}".format(37)
Sparkler

2
f "{37: b}" trong Python3.7 trở lên.
DA

471

Nếu bạn đang tìm kiếm bin()tương đương hex(), nó đã được thêm vào python 2.6.

Thí dụ:

>>> bin(10)
'0b1010'

66
Cũng lưu ý rằng việc thực hiện nhanh hơn str(bin(i))[2:](0.369 giây cho 1000000ops) so với "{0:b}".format(i)(0.721 giây cho 1000000ops)
mVChr

64
@mVChr nếu ai đó chuyển đổi số thành biểu diễn nhị phân ASCII, tôi thực sự hy vọng tốc độ không thành vấn đề.
Nick T

29
@mVChr: str.format()dù sao cũng là công cụ sai, bạn sẽ sử dụng format(i, 'b')thay thế. Hãy tính đến điều đó cũng cung cấp cho bạn các tùy chọn đệm và căn chỉnh mặc dù; format(i, '016b')để định dạng thành số nhị phân không đệm 16 bit. Để làm điều tương tự với bin()bạn, bạn phải thêm mộtstr.zfill() cuộc gọi: bin(i)[2:].zfill(16)(không cần gọi str()!). format()Khả năng đọc và tính linh hoạt (định dạng động khó hơn nhiều bin()) là sự đánh đổi tuyệt vời, đừng tối ưu hóa hiệu suất trừ khi bạn phải, cho đến khi đó tối ưu hóa để duy trì.
Martijn Pieters

[2:] có nghĩa là gì?
zero_cool

4
Tất nhiên, với python 3.6+ bây giờ bạn có thể sử dụng f"{37:b}".
Luke Davis

63

Python thực sự không có một cái gì đó đã được xây dựng trong cho điều này, khả năng làm các hoạt động như '{0:b}'.format(42), mà sẽ cung cấp cho bạn các mẫu bit (trong một chuỗi) cho 42hay 101010.


Đối với một triết lý tổng quát hơn, không có ngôn ngữ hoặc thư viện sẽ cung cấp cho người dùng cơ sở mọi thứ mà họ mong muốn. Nếu bạn đang làm việc trong một môi trường không cung cấp chính xác những gì bạn cần, bạn nên thu thập các đoạn mã khi bạn phát triển để đảm bảo bạn không bao giờ phải viết điều tương tự hai lần. Chẳng hạn như, ví dụ, mã giả:

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

sẽ xây dựng chuỗi nhị phân của bạn dựa trên giá trị thập phân. Chỉ cần ghi nhớ đó là một chút chung của pseudo-code có thể không phải là hầu hết các cách hiệu quả để làm việc đó tuy nhiên, với sự lặp đi lặp lại bạn dường như được đề xuất, nó sẽ không làm cho nhiều sự khác biệt. Nó thực sự chỉ là một hướng dẫn về cách nó có thể được thực hiện.

Ý tưởng chung là sử dụng mã từ (theo thứ tự ưu tiên):

  • ngôn ngữ hoặc thư viện tích hợp.
  • thư viện bên thứ ba với giấy phép phù hợp.
  • bộ sưu tập của riêng bạn.
  • một cái gì đó mới bạn cần viết (và lưu trong bộ sưu tập của riêng bạn cho sau này).

1
Một số lời khuyên tốt trong câu trả lời này. Chỉ quá tệ là mã chậm không cần thiết. Bạn đề xuất một thuật toán O (N ^ 2) trong đó một O (N) sẽ làm. Phần có vấn đề là trong s = "1" + ss = "0" + sdòng. Mỗi bản sao không cần thiết của s. Bạn nên đảo ngược chuỗi ngay trước khi bạn trả lại nó.
Andreas Magnusson

@Andreas, những gì tôi đề xuất là sử dụng '{0:b}'.format(42), phương pháp chậm chỉ đơn giản là một ví dụ về cách thực hiện một cách khái quát, có thể hoặc không thể là O (n ^ 2) tùy thuộc vào ngôn ngữ thực tế được sử dụng. Nó chỉ giống như Python vì Python là ngôn ngữ mã giả lý tưởng nên tôi sẽ thay đổi nó để làm cho nó rõ ràng.
paxdiablo

Trên thực tế, nó sẽ là một ngôn ngữ bí truyền, trong đó s = "1" + skhông phải là O (N) khi slà một kiểu chuỗi. Có thể một ngôn ngữ trong đó tất cả các chuỗi được lưu trữ ngược hoặc mỗi char là một nút trong danh sách được liên kết? Đối với bất kỳ ngôn ngữ điển hình nào, một chuỗi về cơ bản là một mảng các ký tự. Trong trường hợp đó, tiền tố một chuỗi yêu cầu một bản sao được tạo ra, bạn sẽ đặt ký tự khác trước các ký tự khác như thế nào?
Andreas Magnusson

Tôi có thể dễ dàng hình dung ra một loại chuỗi bao gồm một khối bộ nhớ trong đó chuỗi được chứng minh đúng trong khối đó và bù cho ký tự bắt đầu của nó. Để thêm tiền tố vào một ký tự, sau đó bạn chỉ cần giảm phần bù và lưu trữ ký tự ở đó. Vâng, đó sẽ là bí truyền nhưng đối với tôi không có ý nghĩa gì khi tranh luận về các vấn đề thực tế có thể xảy ra với một chút mã giả, đặc biệt là vì bạn không có khả năng có nhiều hơn vài chục bit / lần lặp. Ngay cả loại bong bóng không phù hợp cũng đủ nếu kích thước dữ liệu của bạn nhỏ :-) Trong mọi trường hợp, tôi sẽ thêm một lưu ý về hiệu quả.
paxdiablo

Chắc chắn, nếu hiệu quả là quan trọng, có lẽ bạn không nên chọn python để bắt đầu. Tuy nhiên, theo kinh nghiệm của tôi, nó thường xảy ra mã được viết một cách ngây thơ bằng cách sử dụng thuật toán O (N²) và được thử nghiệm với một tập dữ liệu nhỏ nhanh chóng được sử dụng với tập dữ liệu lớn hơn nhiều vì "nó dường như hoạt động". Sau đó, đột nhiên bạn có mã phải mất hàng giờ để chạy mà khi cố định có thể chỉ mất vài giây. Các thuật toán O (N²) ngấm ngầm bởi vì chúng dường như hoạt động được một thời gian nhưng khi dữ liệu của bạn tăng lên thì không, và sau đó anh chàng đã viết chúng đã bỏ cuộc và không ai biết tại sao mọi việc lại diễn ra mãi mãi.
Andreas Magnusson

41

Nếu bạn muốn một biểu diễn văn bản không có tiền tố 0b, bạn có thể sử dụng:

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

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

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

Khi bạn muốn một đại diện n-bit:

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

Ngoài ra, nếu bạn thích có một chức năng:

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
Hoặc chỉ sử dụng format(integer, 'b'). bin()là một công cụ gỡ lỗi, đặc biệt nhằm tạo ra cú pháp số nguyên nhị phân Python , format()nhằm tạo ra các định dạng cụ thể.
Martijn Pieters

1
@MartijnPieters Cảm ơn bạn rất nhiều vì đã đề cập đến nó. Tôi đã điều chỉnh sự an ủi của mình. Làm thế nào để bạn biết rằng đó bin()là một công cụ sửa lỗi nhằm tạo ra cú pháp số nguyên nhị phân Python? Tôi không thể tìm thấy điều đó trong tài liệu.
Martin Thoma

2
Từ tài liệu: Kết quả là một biểu thức Python hợp lệ . Mục đích của nó là tạo ra một biểu thức Python, không tạo ra các biểu diễn của người dùng cuối. Điều tương tự áp dụng cho oct()hex().
Martijn Pieters

4
Nhiều lựa chọn thay thế khác: Nếu bạn định làm cho chiều rộng động, thay vì str.zfill()bạn có thể sử dụng str.format()hoặc format()với một đối số thứ hai động: '{0:0{1}b}'.format(x, n)hoặc format(b, '0{}b'.format(n)).
Martijn Pieters

@MartijnPieters Wow, cảm ơn bạn rất nhiều vì đầu vào này! Tôi không biết rằng điều này là có thể với định dạng. Tuy nhiên, tôi nghĩ rằng câu trả lời hiện tại của tôi zfilldễ đọc và dễ hiểu hơn so với đối số thứ hai động, vì vậy tôi sẽ giữ nguyên điều đó.
Martin Thoma

38

Để tham khảo:

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

Hàm này có thể chuyển đổi một số nguyên dương lớn bằng 18446744073709551615, được biểu diễn dưới dạng chuỗi '1111111111111111111111111111111111111111111111111111111111111111'.

Nó có thể được sửa đổi để phục vụ một số nguyên lớn hơn nhiều, mặc dù nó có thể không tiện dụng bằng "{0:b}".format()hoặc bin().


@GarethDavidson đây là phiên bản nào? Có điều này được nêu rõ ràng có thể được sử dụng trong tương lai lớn hơn khi googling nó.
Sói

Đó là phiên bản 2.7 tôi nghĩ. Tôi nghi ngờ nó sẽ hoạt động trong 3.x
Gareth Davidson

17

Một cách đơn giản để làm điều đó là sử dụng định dạng chuỗi, xem trang này .

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

Và nếu bạn muốn có một chuỗi nhị phân có độ dài cố định, bạn có thể sử dụng:

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

Nếu bổ sung hai là bắt buộc, thì dòng sau có thể được sử dụng:

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

Trong đó n là chiều rộng của chuỗi nhị phân.


16

Đây là cho python 3 và nó giữ các số không hàng đầu!

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

nhập mô tả hình ảnh ở đây


1
Tôi đánh giá cao câu trả lời đơn giản.
reergymerej

14

một lớp lót với lambda :

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

kiểm tra:

>>> binary(5)
'101'



CHỈNH SỬA :

nhưng sau đó :(

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

so với

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

trả về '' cho 0 mặc dù. Không phải đại diện bình thường cho 0 là '0'?
dietbacon

nếu bạn muốn thấy 0 :), bạn có thể thay thế ''bằng '0', nhưng nó sẽ thêm số 0 đứng đầu cho bất kỳ số nào.
Aziz Alto

11

Tóm tắt các lựa chọn thay thế:

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.

Những người đóng góp bao gồm John Fouhy , Tung Nguyen , mVChr , Martin Thoma . và Martijn Pieters.


6
str.format()chỉ để định dạng một giá trị là quá mức cần thiết. Đi thẳng đến format()chức năng : format(n, 'b'). Không cần phải phân tích chỗ giữ chỗ và khớp nó với một đối số theo cách đó.
Martijn Pieters



5

Sử dụng gói numpy / unpackbits, họ là những người bạn tốt nhất của bạn.

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)

Câu hỏi là về một đại diện chuỗi . Tuy nhiên, điều này đã xảy ra chỉ là những gì tôi đang tìm kiếm mà không cần thông qua chuỗi đầu tiên! :)
Tom Hale

Các doco nói: yếu tố của một giải nén uint8mảng thành một mảng đầu ra nhị phân có giá trị. Rất tốt cho các giá trị lên tới 255.
Tom Hale

5

Đối với những người trong chúng ta, những người cần chuyển đổi số nguyên đã ký (phạm vi -2 ** (chữ số-1) thành 2 ** (chữ số-1) -1) thành chuỗi nhị phân bổ sung của 2, điều này hoạt động:

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

Điều này tạo ra:

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


4

Một giải pháp khác với thuật toán khác, bằng cách sử dụng các toán tử bitwise.

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

Một phiên bản nhanh hơn mà không đảo ngược chuỗi.

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

Phiên bản thứ hai chắc chắn không nhanh hơn khi bạn kết thúc bằng một thuật toán như O (N ^ 2) thay vì O (N). Tôi đã thấy những thứ như thế này giết chết một ứng dụng (hiệu năng-khôn ngoan) bởi vì nhà phát triển nghĩ rằng việc thực hiện thêm một lượt vào cuối chậm hơn so với thực hiện một số nội dung bổ sung trong vòng lặp đầu tiên. Sau khi cố định, thời gian chạy giảm từ vài ngày xuống vài giây.
Andreas Magnusson

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

print binary(10)

đầu ra:

1010


4

bạn có thể làm như thế:

bin(10)[2:]

hoặc là :

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

bin (n) .replace ("0b", "")
sanner little

3

Đây là mã tôi vừa thực hiện. Đây không phải là một phương pháp nhưng bạn có thể sử dụng nó như một chức năng sẵn sàng để sử dụng !

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

đây là giải pháp đơn giản sử dụng fucntion divmod () trả về lời nhắc và kết quả của phép chia không có phân số.

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

Cần gỡ lỗi. dectobin(10)Kết quả cuộc gọi trong '0101'
Nate


3

numpy.binary_repr(num, width=None)

Ví dụ từ liên kết tài liệu ở trên:

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

Phần bù của hai được trả về khi số đầu vào là âm và chiều rộng được chỉ định:

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

2

Giải pháp tương tự

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

Đây là một cách khác để sử dụng toán học thông thường, không có vòng lặp, chỉ đệ quy. (Trường hợp tầm thường 0 không trả về gì).

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

Máy tính có tất cả các chức năng cần thiết cho DEC, BIN, HEX: (được tạo và thử nghiệm với Python 3.5)

Bạn có thể thay đổi số kiểm tra đầu vào và lấy số đã chuyển đổi.

# 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

Để tính nhị phân của các số:

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

Để tính số thập phân Hexa của một số :

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

Để tính tất cả các nhị phân cho đến 16 ::

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

Để tính thập phân Hexa cho đến 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

1

Nếu bạn sẵn sàng từ bỏ Python "thuần túy" nhưng có được nhiều hỏa lực, thì có Sage - ví dụ ở đây :

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

Bạn sẽ lưu ý rằng nó trả về dưới dạng một chuỗi, vì vậy, để sử dụng nó như một số bạn muốn làm một cái gì đó như

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
Có thể muốn thêm một số lời giải thích cho những gì bạn đã làm ở đó.
Artless

1

Tôi tìm thấy một phương pháp sử dụng ma trận hoạt động để chuyển đổi thập phân thành nhị phân.

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)

Elà dữ liệu thập phân đầu vào, Mlà các lệnh nhị phân. bindatalà dữ liệu nhị phân đầu ra, có định dạng 1 ma trận nhị phân M.


0

Đây là một công cụ chuyển đổi nhị phân sang thập phân đơn giản liên tục lặp

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

    print(convertedNumber)

print("")

Đây là thứ tự ngược lại của những gì OP muốn. Họ đang tìm kiếm int để nhị phân. Bạn cung cấp nhị phân cho int.
Trương Bá Chi

0

Đây là câu trả lời của tôi nó hoạt động tốt ..!

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

Nếu bạn vượt qua giá trị 0thì sao? Ví dụ, binary(0)bạn sẽ nhận được những gì bạn mong đợi?
Andreas Magnusson
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.