2012-10-26 27 views
6

Tôi có các tình huống sau:Chuyển đổi nhị phân để liệt kê các chữ số Python

x = 0b0111 

Tôi muốn chuyển đổi giá trị này để:

y = [0, 1, 1, 1] 

Khi tôi chuyển đổi x = 0b1001, tôi có thể nhận y = [1, 0, 0, 1], nhưng khi tôi cố gắng làm tương tự cho x = 0b0111 và sau đó chuyển đổi lại với str(bin(y)) - Tôi dường như mất số 0 hàng đầu và nhận được 0b111.

Mọi đề xuất?

+1

'0b0111 == 0b111' vậy vấn đề là gì? Nếu bạn cần danh sách có độ dài cố định, thì chỉ cần tack số tiền thích hợp là 0 vào đầu. –

Trả lời

3

Đầu chuyển đổi số nhị phân và sau đó đến chuỗi:

str(bin(7)) 
'0b111' #note the 0b in front of the binary number 

Tiếp theo, loại bỏ các 0b từ chuỗi

str(bin(7))[2:] 
'111' 

Cuối cùng chúng ta sử dụng danh sách hiểu biết để tạo ra một danh sách các ints từ chuỗi, trong đó có khoảng biểu mẫu sau:

[expr for i in iterable] 
[int(i) for i in str(bin(x))[2:]] 
+0

Vui lòng giải thích câu trả lời cho OP cũng như với mã. –

6

Khi bạn nhận được chuỗi đó 0b111, thật đơn giản để tách các chữ số mà bạn quan tâm. Đối với mỗi ký tự của mọi thứ sau 0b trong chuỗi, hãy chuyển đổi nó thành số nguyên.

[int(d) for d in str(bin(x))[2:]] 
1

Biểu thức như map(int, list(bin((1<<8)+x))[-4:]) sẽ cung cấp cho bạn 4 bit thấp của một số, dưới dạng danh sách. (Chỉnh sửa: Biểu mẫu sạch hơn làmap(int,bin(x)[2:].zfill(4)); xem bên dưới.) Nếu bạn biết số lượng bit bạn muốn hiển thị, hãy thay thế số 4 (trong số [-4:]) bằng số đó; và làm cho số 8 (trong số (1<<8)) một số lớn hơn nếu cần. Ví dụ:

>>> x=0b0111 
>>> map(int,list(bin((1<<8)+x))[-4:]) 
[0, 1, 1, 1] 
>>> x=37; map(int,list(bin((1<<8)+x))[-7:]) 
[0, 1, 0, 0, 1, 0, 1] 
>>> [int(d) for d in bin((1<<8)+x)[-7:]] 
[0, 1, 0, 0, 1, 0, 1] 

Ví dụ cuối cùng ở trên cho thấy thay thế cho việc sử dụng bản đồ và danh sách. Các ví dụ sau đây cho thấy một hình thức hơi sạch hơn để có được số 0 hàng đầu. Trong những hình thức, thay thế số lượng tối thiểu mong muốn của các bit ở vị trí của 8.

>>> x=37; [int(d) for d in bin(x)[2:].zfill(8)] 
[0, 0, 1, 0, 0, 1, 0, 1] 
>>> x=37; map(int,bin(x)[2:].zfill(8)) 
[0, 0, 1, 0, 0, 1, 0, 1] 
>>> x=37; map(int,bin(x)[2:].zfill(5)) 
[1, 0, 0, 1, 0, 1] 
>>> x=37; map(lambda k:(x>>-k)&1, range(-7,1)) 
[0, 0, 1, 0, 0, 1, 0, 1] 
0

kiểm tra theo cách này đơn giản để làm điều đó ... cho kịch bản đặc biệt này

In [41]: x=0b0111 

In [42]: l = [0,0,0,0] 

In [43]: counter = -1 

In [44]: for i in str(bin(x))[2:]: 
    ....:  l[counter] = i 
    ....:  counter = counter -1 
    ....: 

In [45]: l 
Out[45]: [0, '1', '1', '1'] 
0
c=[] 
for i in bin(7)[2:]: 
     c.append(int(i)) #turning string "111", to 111 
if len(c)==3: 
    c.insert(0,0) 
print(c) 

# binary digit 7 produces '0b111' by this slicing[2:], result get '111' 

vì vậy nếu yếu tố trong danh sách c là 3, 0 được chèn trước.

+1

Vui lòng đăng một số giải thích về câu trả lời là tốt. –

3

Đối với những gì nó có giá trị, một giải pháp số học thuần túy dường như là nhẹ nhanh hơn:

import timeit 

def bits1(n): 
    b = [] 
    while n: 
     b = [n & 1] + b 
     n >>= 1 
    return b or [0] 

timeit.timeit(lambda: bits1(12345678)) 
[out] 7.717339038848877 

def bits2(n): 
    return map(int, list(bin(n)[2:])) 

timeit.timeit(lambda: bits2(12345678)) 
[out] 10.297518014907837 
0

Nếu độ dài của các bit được cố định 4, có hai giải pháp:

[int(i) for i in '{0:04b}'.format(0b0111)] 

hoặc với NumPy,

import numpy as np 
[int(i) for i in np.binary_repr(0b0111, 4)] 
Các vấn đề liên quan