将整数列表扩展为1-out-of-n二进制列表

时间:2016-11-18 15:11:58

标签: python list python-3.x

如果最大列表l的大小为r的整数为N位,我该如何创建一个大小为binaryL的列表r*N,其中值反映了l的正位?

示例,对于N=2位:

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

变为

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

其中每组r个整数等于每个位。换句话说,第一个0, 0, 1l的第一位,最后的1, 0, 1l的最后一位。

另一个选择是按顺序获取位,其中

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

在这种情况下,每个值都会转换为其位。

对于那些对性能感到疑惑的人,

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)

打印1000个值:

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

和10.000.000值

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

3 个答案:

答案 0 :(得分:1)

希望这就是你所需要的:

l=[3,4,5,6,7,8]
binaryL = []
for i in l:
    binaryL += [int(b) for b in "{0:b}".format(i).rjust(4, '0')]

答案 1 :(得分:1)

使用bin将整数转换为二进制表示形式,并使用zfill()将结果填充到指定长度,使用chain将列表展平,并使用{{1}将字符串转换为int }:

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] ,另一个选项可能是:

chain

转置版本:

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

答案 2 :(得分:1)

对于更容易检查的更明显的解决方案,可以使用常规for循环。我对表演没有任何承诺。 (看起来很快。)

n = 2 # Max method can be used to find this. As expressed in other answers.
r = 3
l = [1, 0, 3]
new_list = [0] * n * r  # list is prefilled.
                        # Construction similar to C type programming.

for ind, binary in enumerate(map(bin, l)):
    for ind_bit, bit in enumerate(binary[2:].zfill(n)):
        new_list[r * ind_bit + ind] = bit

print new_list

请注意,我在Python 2上写了这个,请对Python 3进行小改动。

修改:这会在您的问题中找到第一个binaryL,而不是您之后添加的{{1}},这样更容易,因为需要简单的追加。