Питонический способ перебора битов целого числа

Давайте a = 109 или 1101101 в двоичном формате. Как перебирать биты этого числа, например: [64, 32, 8, 4, 1]

27
задан dmzkrsk 17 January 2012 в 17:13
поделиться

4 ответа

Есть хитрость, заключающаяся в том, чтобы просто получить 1 из двоичного представления без необходимости перебирать все промежуточные 0:

def bits(n):
    while n:
        b = n & (~n+1)
        yield b
        n ^= b


>>> for b in bits(109):
    print(b)


1
4
8
32
64
46
ответ дан 28 November 2019 в 04:36
поделиться

Эффективность ответа Ф.Дж. может быть значительно улучшена.

from itertools import count,takewhile
[2**i for i in takewhile(lambda x:109>2**x,count()) if 109&2**i][::-1]

Мне нравится один вкладыш:)

Я сделал быстрый timeit.Timer.timeit () против этого и @Duncan. Дункан все еще выигрывает, но не один лайнер, по крайней мере, в том же классе.

from timeit import Timer
duncan="""\
def bits(n):
 while n:
  b=n&(~n+1)
  yield b
  n^=b
"""
Duncan=Timer('list(bits(109))[::-1]',duncan)
Duncan.timeit()
4.3226630687713623
freegnu=Timer('[2**i for i in takewhile(lambda x:109>2**x,count()) if 109&2**i][::-1]','from itertools import count,takewhile')
freegnu.timeit()
5.2898638248443604
0
ответ дан 28 November 2019 в 04:36
поделиться
>>> [2**i for i, v in enumerate(bin(109)[:1:-1]) if int(v)]
[1, 4, 8, 32, 64]

Очевидно, что здесь порядок обратный, вы можете просто использовать это или поменять местами результат:

>>> [2**i for i, v in enumerate(bin(109)[:1:-1]) if int(v)][::-1]
[64, 32, 8, 4, 1]

изменить: Вот немного более длинная версия, которая должна быть более эффективный:

from itertools import takewhile, count
[p for p in takewhile(lambda x: x <= 109, (2**i for i in count())) if p & 109]
7
ответ дан 28 November 2019 в 04:36
поделиться

Пример однострочного решения:

[1 << bit for bit in xrange(bitfield.bit_length()) if bitfield & (1 << bit)]

Или:

[bit for bit in (1 << n for n in xrange(bitfield.bit_length())) if bitfield & bit]

Примечания:

  • использовать диапазон в Python 3
  • подумать о проверке битового поля> = 0
0
ответ дан 28 November 2019 в 04:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: