17

私はint(リスト内の)ビットフィールドに変換するメソッドを作成しましたが、それは機能しますが、もっとエレガントな解決策があると確信しています-私は長い間それを見つめてきました。

私は興味があります、どのようにあなたは?intで表されるビットフィールドに変換しlistますか?

def get(self):
    results = []

    results.append(1 if (self.bits &   1) else 0)
    results.append(1 if (self.bits &   2) else 0)
    results.append(1 if (self.bits &   4) else 0)
    results.append(1 if (self.bits &   8) else 0)
    results.append(1 if (self.bits &  16) else 0)
    results.append(1 if (self.bits &  32) else 0)
    results.append(1 if (self.bits &  64) else 0)
    results.append(1 if (self.bits & 128) else 0)

    return results

def set(self, pin, direction):
    pin -= 1
    if pin not in range(0, 8): raise ValueError

    if direction: self.bits |= (2 ** pin)
    else: self.bits &=~(2 ** pin)
4

6 に答える 6

37

これはどう:

def bitfield(n):
    return [int(digit) for digit in bin(n)[2:]] # [2:] to chop off the "0b" part 

これはあなたに

>>> bitfield(123)
[1, 1, 1, 1, 0, 1, 1]
>>> bitfield(255)
[1, 1, 1, 1, 1, 1, 1, 1]
>>> bitfield(1234567)
[1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1]

ただし、これは正の整数に対してのみ機能します。

編集:

intここでは、使用への変換int()は少しやり過ぎです。これははるかに高速です:

def bitfield(n):
    return [1 if digit=='1' else 0 for digit in bin(n)[2:]]

タイミングを参照してください。

>>> import timeit
>>> timeit.timeit("[int(digit) for digit in bin(123)[2:]]")
7.895014818543946
>>> timeit.timeit("[123 >> i & 1 for i in range(7,-1,-1)]")
2.966295244250407
>>> timeit.timeit("[1 if digit=='1' else 0 for digit in bin(123)[2:]]")
1.7918431924733795
于 2012-04-25T18:54:57.060 に答える
27

これは使用しませんbin

 b = [n >> i & 1 for i in range(7,-1,-1)]

これは、この方法で整数を処理する方法です。

 b = [n >> i & 1 for i in range(n.bit_length() - 1,-1,-1)]

を参照してくださいbit_length

リストのインデックス0をintのlsbに対応させる場合は、範囲の順序を変更します。

b = [n >> i & 1 for i in range(0, n.bit_length()-1)]

固定長のバイナリ値を表現しようとしている場合、n.bit_length()の使用が障害点になる可能性があることにも注意してください。nを表す最小ビット数を返します。

于 2012-04-25T19:02:52.113 に答える
4

試す

>>>n=1794
>>>bitfield=list(bin(n))[2:]
>>>bitfield
['1', '1', '1', '0', '0', '0', '0', '0', '0', '1', '0']

ただし、これは負のnでは機能しません。ご覧のとおり、文字列のリストが表示されます。

于 2012-04-25T19:01:13.947 に答える
1

負の値では機能しません

>>> import numpy as np
>>> [int(x) for x in np.binary_repr(123)]
[1, 1, 1, 1, 0, 1, 1]
于 2018-11-29T17:03:54.770 に答える
1

固定長の配列

固定長の配列:

>>> '{0:07b}'.format(12)
'0001100'

文字列も配列だと思いますか?いいえ?見る:

>>> [int(x) for x in '{0:07b}'.format(12)]
[0, 0, 0, 1, 1, 0, 0]
于 2020-11-25T06:54:20.187 に答える
0

私は、intから値を取得するためのテンプレートを指定する私のプログラムに対してこれを行っています。

def field(template, value):
    sums = [int(v) if v.__class__==str else len(bin(v))-2 for v in template]
    return [(value>> (sum(sums[:i]) if i else 0) )&(~(~0<<int(t)) if t.__class__==str else t) for i,t in enumerate(template)]

テンプレートでの使用方法
、ビットサイズに関連するintを指定します。

field([0b1,0b111,0b1111], 204) #>>> [0, 6, 12]

または、文字列を使用して必要な各値のビットサイズを指定できます:( noobフレンドリー)

field(['1','3','4'], 204) #>>> [0, 6, 12]

編集:およびその逆:(別のコード)

field(['1','3','4'], [0, 6, 12]) #>>> 204
field([0b1,0b111,0b1111], [0,3,9]) #>>> 150

コード:

def field(template, value):
    res = 0
    for t, v in zip(template, value)[::-1]: res = (res << (t.bit_length() if t.__class__ is int else int(t)) )|v
    return res

EDIT2:より高速なコード^

于 2015-05-26T04:40:19.797 に答える