2016-11-18 53 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