2016-10-15 28 views
1

高效的方式非常大名單對名單進行異或運算,使得XOR其旋轉

如:

#here a,b,c,d are integers 
L = [a,b,c,d] 
N = [b,c,d,a] #right rotation of list L 

Newlist = enter code here[a^b, b^c, c ^d ,d^a] 

爲列表的大小是非常大的,有沒有解決任何有效的方式。

這是迄今爲止我所做的。

#right rotation of list 
def shift(seq, n): 
    n = n % len(seq) 
    return seq[n:] + seq[:n] 

L = [6,7,1,3] 
N = shift(L,1) 
new = [] 
for i,j in zip(L,N): 
    new.append(i^j) 
print(new) 

回答

3

你可以試試下面的事項:

from collections import deque 

L = [6, 7, 1, 3] 
L2 = deque(L) 
L2.rotate(-1) # rotate to left 
result = [i^j for i, j in zip(L, L2)] 

這可能是至少稍快。

其他的解決辦法是要檢查這種可能性:

from itertools import islice 
L = [6, 7, 1, 3] 
# This will add all the XoRs except for the last pair (6, 3) 
result = [i^j for i, j in zip(L, islice(L, 1, len(L))] 
# adding the last XOR 
result.append(L[0]^[L-1]) 
print(result) 
[1, 6, 2, 5] 
+0

除了構建並返回新列表的列表片段之外,您應該使用'itertools.islice'來提高空間效率。 –

+0

@ juanpa.arrivillaga完成。 – Nf4r

0

這是另一種方法。我寫的發電機可能可以改進,但它給你的想法。這是節省空間,因爲你不是建立一個新的列表:

>>> def rotation(lst,n): 
... for i in range(len(lst)): 
...  yield lst[(i + n) % len(lst)] 
... 
>>> L = [1,2,3,4,5] 
>>> list(rotation(L,1)) 
[2, 3, 4, 5, 1] 
>>> [a^b for a,b in zip(L,rotation(L,1))] 
[3, 1, 7, 1, 4] 

定義rotation的另一種方法是:

>>> def rotation(lst,n): 
... yield from (lst[(i + n) % len(lst)] for i in range(len(lst))) 
... 
>>> L = ['a','b','c','d'] 
>>> ["{}^{}".format(i,j) for i,j in zip(L,rotation(L,1))] 
['a^b', 'b^c', 'c^d', 'd^a'] 
0

這裏的另一種方法!

我定義了一個函數,給定一個索引,返回該索引處的數字以及它的下一個鄰居在「right」上作爲一對(a, b),然後XOR那些。給它的索引超出列表的範圍也是安全的。所以:

def rotate_and_xor(l): 
    def get_pair_xor(i): 
     i %= len(l) 
     j = (i + 1) % len(l) 
     return l[i]^l[j] 

    return list(map(get_pair_xor, range(len(l)))) 

我不建議這是最好的解決方案;我只是想以不同的方式解決它。使用像其他人一樣的列表推斷可能是更多的Pythonic,但我喜歡使用map