Список бит для целого числа в Python
У меня есть такой список в Python: [1,0,0,0,0,0,0,0]
. Можно ли преобразовать его в целое число, например, как я набрал 0b10000000 (т.е. Преобразовать в 128)?
Мне также нужно преобразовать последовательности, такие как [1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0]
в целые числа (здесь он вернет 0b1100000010000000, т.е. 259).
Длина списка всегда кратно 8, если это необходимо.
Ответы
Ответ 1
Вы можете использовать bithifting:
out = 0
for bit in bitlist:
out = (out << 1) | bit
Это легко удаляет метод "int cast", предложенный A. R. S., или модифицированный литой с поиском, предложенный Стивеном Румбальским:
>>> def intcaststr(bitlist):
... return int("".join(str(i) for i in bitlist), 2)
...
>>> def intcastlookup(bitlist):
... return int(''.join('01'[i] for i in bitlist), 2)
...
>>> def shifting(bitlist):
... out = 0
... for bit in bitlist:
... out = (out << 1) | bit
... return out
...
>>> timeit.timeit('convert([1,0,0,0,0,0,0,0])', 'from __main__ import intcaststr as convert', number=100000)
0.5659139156341553
>>> timeit.timeit('convert([1,0,0,0,0,0,0,0])', 'from __main__ import intcastlookup as convert', number=100000)
0.4642159938812256
>>> timeit.timeit('convert([1,0,0,0,0,0,0,0])', 'from __main__ import shifting as convert', number=100000)
0.1406559944152832
Ответ 2
... или используя bitstring модуль
>>> from bitstring import BitArray
>>> bitlist=[1,0,0,0,0,0,0,0]
>>> b = BitArray(bitlist)
>>> b.uint
128
Ответ 3
Я наткнулся на метод, который немного превосходит решение Martijn Pieters, хотя его решение красивее, конечно. Я на самом деле немного удивлен результатами, но в любом случае...
import timeit
bit_list = [1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0]
def mult_and_add(bit_list):
output = 0
for bit in bit_list:
output = output * 2 + bit
return output
def shifting(bitlist):
out = 0
for bit in bitlist:
out = (out << 1) | bit
return out
n = 1000000
t1 = timeit.timeit('convert(bit_list)', 'from __main__ import mult_and_add as convert, bit_list', number=n)
print "mult and add method time is : {} ".format(t1)
t2 = timeit.timeit('convert(bit_list)', 'from __main__ import shifting as convert, bit_list', number=n)
print "shifting method time is : {} ".format(t2)
Результат:
mult and add method time is : 1.69138722958
shifting method time is : 1.94066818592
Ответ 4
Попробуйте использовать один слой:
int("".join(str(i) for i in my_list), 2)
Если вы обеспокоены скоростью/эффективностью, взгляните на решение Martijn Pieters.
Ответ 5
как насчет этого:
out = sum([b<<i for i, b in enumerate(my_list)])