¿Cómo convierto un número entero a una lista de bits en Python?

Me gustaría saber si hay una forma mejor de hacerlo que mi método actual.

Estoy tratando de representar un número entero como una lista de bits y lo dejé en 8 bits solo si el número entero es <128 :

Example input: 0x15 Desired output: [0, 0, 0, 1, 0, 1, 0, 1] 

Lo hago de la siguiente manera:

 input = 0x15 output = deque([int(i) for i in list(bin(input))[2:]]) while len(output) != 8: output.appendleft(0) 

¿Hay una mejor manera de hacer esto en python?

EDITAR: Me gustaría convertir cualquier número entero a una lista binaria. Rellene a 8 solo si el número requiere menos de 8 bits para representar.

 Another Example input: 0x715 Desired output: [1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1] 

 input = 0x15 output = [int(x) for x in '{:08b}'.format(input)] 

{0:0=8b}'.format(0x15) representa su input en formato binary con un 0 padding a 8 dígitos, y luego utiliza la comprensión de lista para crear una lista de bits.

Alternativamente, puede utilizar la función de map :

output = map(int, [x for x in '{:08b}'.format(0x15)])

EDIT: ancho de bit variable,

Si quieres hacer que la cantidad de bits sea variable, aquí hay una forma:

 width = 8 #8bit width output = [int(x) for x in '{:0{size}b}'.format(0x15,size=width)] output = map(int, [x for x in '{:0{size}b}'.format(0x15,size=width)]) 

Esto fue probado en Python 2.7

 >>> [int(n) for n in bin(0x15)[2:].zfill(8)] [0, 0, 0, 1, 0, 1, 0, 1] 

La división [2:] es eliminar el prefijo 0b , zfill(8) es rellenar los ceros a la izquierda.

Para un tamaño fijo de 8 bits:

 num = 0x15 out = [1 if num & (1 << (7-n)) else 0 for n in range(8)] 

El (1 << (7-n)) crea una máscara de un solo bit para una posición dada, y luego a nivel de bits & prueba para ver si ese bit está establecido en el número. Tener n trabajo entre 0 y 7 resultados en todos los 8 bits en el byte que se está probando en orden.

Para números de tamaño arbitrario:

 import math num = 0x715 bits = int(max(8, math.log(num, 2)+1)) out = [1 if num & (1 << (bits-1-n)) else 0 for n in range(bits)] 

Es fácil hacer esto con cadenas de formato

 >>> "{:08b}".format(0x15) '00010101' >>> "{:08b}".format(0x151) '101010001' >>> "{:08b}".format(0x1511) '1010100010001' 

para convertir a una lista

 >>> [1 if x=='1' else 0 for x in "{:08b}".format(0x15)] [0, 0, 0, 1, 0, 1, 0, 1] >>> [1 if x=='1' else 0 for x in "{:08b}".format(0x1511)] [1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1] 

Es probable que sea más rápido con el twiddling de bits como en la respuesta de @Ambar, pero luego tendrás que buscar casos especiales y terminar con un poco de código. Si no se requiere el máximo rendimiento, es más seguro aprovechar lo que ya sabe que funciona

Puede desplazar el número x pasos a la derecha y luego hacer un bit a bit y el resultado con 1 para obtener el bit en la posición x , haga esto con comprensión de lista y obtendrá su lista. Si necesita admitir números negativos, es posible que debamos agregar un cero inicial a la lista para garantizar que los números positivos no comiencen con un 1:

 import math def bits(n): # The number of bits we need to represent the number num_bits = max(8, int(math.log(abs(n), 2)) + 1) # The bit representation of the number bits = [ (n >> i) & 1 for i in range(num_bits) ] bits.reverse() # Do we need a leading zero? if n < 0 or bits[0] == 0: return bits return [0] + bits # Examples for n in (-0x15, 0x15, 128, 255, 256, -256): print("{: 4} = {}".format(n, bits(n))) 
  -21 = [1, 1, 1, 0, 1, 0, 1, 1] 21 = [0, 0, 0, 1, 0, 1, 0, 1] 128 = [0, 1, 0, 0, 0, 0, 0, 0, 0] 255 = [0, 1, 1, 1, 1, 1, 1, 1, 1] 256 = [0, 1, 0, 0, 0, 0, 0, 0, 0, 0] -256 = [1, 0, 0, 0, 0, 0, 0, 0, 0] 
 from math import ceil input = 0x15 bin_string = bin(input)[2:] binary = map(int,bin_string.zfill(int(ceil(len(bin_string)/8.0)*8))) print(binary) 

Esto redondeará al múltiplo de 8 más cercano, si desea redondear al múltiplo de 8 solo si es <128, use una instrucción simple if else y elimine zfill de else

Salida para 0x15:

 [0, 0, 0, 1, 0, 1, 0, 1] 

Salida para 0x715:

 [0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1] 

Si solo desea agregar ceros si son menos de 128, use esto:

 input = 0x715 bin_string = bin(input)[2:] num_bits = (8 if input < 128 else 0) binary = map(int,bin_string.zfill(num_bits)) print(binary) 

Salida para 0x15:

 [0, 0, 0, 1, 0, 1, 0, 1] 

Salida para 0x715:

 [1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1]