2016-11-18 54 views
2

给定的最大列表l大小为整数rN位,怎么做我创建大小r*N列表binaryL其中的值反映的l正位?扩展整数列表1 - 外的n个二进制列表

实施例,用于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 
+0

为什么'[01,00,11]'变成'[0,0,1,1,0,1]'而不是'[0,1,0,0,1,1]'? –

+0

为清晰起见编辑 – BlueMoon93

回答

1

使用bin到整数的结果转换成二进制表示,并且垫指定的长度与zfill(),与chain弄平列表,并转换与map为int字符串:

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] 

A将换位版本:

list(map(int, chain.from_iterable(zip(*[bin(i)[2:].zfill(N) for i in l])))) 
# [0, 0, 1, 1, 0, 1] 
+2

Might想在这里使用'N = max(l).bit_length()'... –

+0

@JonClements好点。编辑。 – Psidom

+0

这是否比neverwalkaloner的回答更快?我应该运行性能测试来检查这一点,或者有'list','map','chain'等一些明显的优势吗? – BlueMoon93

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')] 
+0

我可以使用它,但是如何让每个值具有相同的尺寸? '3'只给了我两位数字,但'8'给了我4.我如何得到每个数值的4位数字(或“N”数字)? – BlueMoon93

+0

BlueMoon93你可以使用rjust()方法追加带前导零的字符串:res + = [int(b)for b in“{0:b}”.format(i).rjust(4,'0')] – neverwalkaloner

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您问题不是你以后添加的问题,这很容易,因为需要简单的追加。

+0

对于原始问题,表现最佳。 GJ – BlueMoon93