次のシナリオがあります。
x = 0b0111
この値を次のように変換したいと思います。
y = [0, 1, 1, 1]
変換するx = 0b1001
と を取得できますy = [1, 0, 0, 1]
が、同じことをx = 0b0111
で実行してから変換して戻すとstr(bin(y))
、先頭が失われ0
、 を取得するように見えます0b111
。
助言がありますか?
Once you get that string 0b111
, it's straightforward to split out the digits that you're interested in. For each character of everything after the 0b
in the string, convert it to an integer.
[int(d) for d in str(bin(x))[2:]]
価値のあることとして、純粋な算術ソリューションはわずかに高速であるように見えます。
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 [int(x) for x in bin(n)[2:]]
timeit.timeit(lambda: bits2(12345678))
[out] 10.297518014907837
2019アップデート:Python 3.7.3では、2番目のバージョンがわずかに高速です。
最初に数値をバイナリに変換してから、文字列に変換します。
str(bin(7))
'0b111' #note the 0b in front of the binary number
0b
次に、文字列からを削除します
str(bin(7))[2:]
'111'
最後に、リスト内包表記を使用して、文字列から int のリストを作成します。これは、おおよそ次の形式になります。
[expr for i in iterable]
[int(i) for i in str(bin(x))[2:]]
次のような式map(int, list(bin((1<<8)+x))[-4:])
は、数値の下位 4 ビットをリストとして提供します。(編集: よりきれいな形式は map(int,bin(x)[2:].zfill(4))
; 以下を参照してください。) 表示するビット数がわかっている場合は、( の[-4:]
) 4 をその数値に置き換えます。必要に応じて、8 (の(1<<8)
) をより大きな数にします。例えば:
>>> 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]
上記の最後の例は、map と list を使用する代わりの方法を示しています。次の例は、先行ゼロを取得するための、少しきれいな形式を示しています。これらの形式では、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]
この簡単な方法を確認してください...この特定のシナリオについて
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']
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'
したがって、リスト c の要素が 3 の場合、最初に 0 が挿入されます。
これは、文字列の解析を必要としない単純なオンライン ライナーです。
[x >> bin_idx & 1 for bin_idx in reversed(range(x.bit_length()))]
ここに投稿された他の回答よりも少し速いと思います。