Reputation: 1047
Efficient way to XOR on list such that,
eg:
#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]
as size of list is very large, is there any efficient way to solve.
this is so far what i have done.
#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)
Upvotes: 1
Views: 276
Reputation: 1410
You can try to check this:
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)]
This might be at least slightly faster.
Other solution would be to check this possibility:
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]
Upvotes: 3
Reputation: 2200
Here's another method!
I define a function that, given an index, returns the number at that index and its next neighbor on the "right" as a pair (a, b)
, and then XOR those. It is also safe to give it indices outside the range of the list. So:
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))))
I don't propose that this is necessarily the best solution; I just wanted to solve it a different way. Using list comprehensions like the others suggest is probably more Pythonic, but I like using map
.
Upvotes: 0
Reputation: 96257
Here is another approach. The generator I've written could probably be improved, but it gives you the idea. This is space efficient, because you are not building a new list:
>>> 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]
An alternative way to define rotation
would be:
>>> 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']
Upvotes: 0