BlueMoon93 - 1 year ago 67
Python Question

Extending integer list to 1-out-of-n binary list

Given maximum a list

`l`
with size
`r`
of integers with
`N`
bits, how to do I create a list
`binaryL`
with size
`r*N`
where the values reflect the positive bits of
`l`
?

Example, for
`N=2`
bits:

`l = [1, 0, 3] --> [01, 00, 11] (in bits)`

becomes

`binaryL = [0, 0, 1, 1, 0, 1]`

where each group of
`r`
integers equals each bit. In other words, the first
`0, 0, 1`
is the first bit of
`l`
, and the final
`1, 0, 1`
is the last bit of
`l`
.

Another option is to just obtain the bits in their order, where

`binaryL = [0, 1, 0, 0, 1, 1]`

In this case, each value is converted to its bits.

``````import random
from itertools import chain
import time

N=8
l=[random.randrange(1,2**N,1) for _ in range (10000000)]
r=len(l)

a = time.clock()
res1 = []
for i in l:
res1 += [int(b) for b in "{0:b}".format(i).rjust(N, '0')]

b = time.clock()
res2 = list(map(int, chain.from_iterable(bin(i)[2:].zfill(N) for i in l)))

c = time.clock()
res3 = list(map(int, ''.join(bin(i)[2:].zfill(N) for i in l)))

d = time.clock()
res4 = [0] * N * r
for ind, binary in enumerate(map(bin, l)):
for ind_bit, bit in enumerate(binary[2:].zfill(N)):
res4[r * ind_bit + ind] = int(bit)

e = time.clock()
res5 = list(map(int, chain.from_iterable(zip(*[bin(i)[2:].zfill(N) for i in l]))))

f = time.clock()

# res1, res2 and res3 are show bits by value. res4 and res5 shows bits by index
print(res1==res2)
print(res2==res3)

print(res4==res5)

print(b-a)
print(c-b)
print(d-c)
print(e-d)
print(f-e)
``````

prints for 1000 values:

``````True
True
True
0.003963000000000001  # neverwalkaloner
0.0025400000000000006 # Psidom1
0.0023320000000000007 # Psidom2
0.004358000000000001  # Rockybilly
0.0021629999999999983 # Psidom3
``````

and for 10.000.000 values

``````True
True
True
36.333539           # neverwalkaloner
25.674224000000002  # Psidom1
24.49611499999999   # Psidom2
47.370771000000005  # Rockybilly
66.25204            # Psidom3
``````

Use `bin` to convert integer to binary representation, and pad the result to specified length with `zfill()`, flatten the list with `chain` and convert the string to int with `map`:

``````from itertools import chain

l = [1, 0, 3]
N = max(l).bit_length()           # as commented by @Jon, use this to determine the maximum
# bit length

list(map(int, chain.from_iterable(bin(i)[2:].zfill(N) for i in l)))

# [0, 1, 0, 0, 1, 1]
``````

Without using `chain`, another option could be:

``````list(map(int, ''.join(bin(i)[2:].zfill(N) for i in l)))
# [0, 1, 0, 0, 1, 1]
``````

A transposed version:

``````list(map(int, chain.from_iterable(zip(*[bin(i)[2:].zfill(N) for i in l]))))
# [0, 0, 1, 1, 0, 1]
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download