Rehan Shikkalgar
Rehan Shikkalgar

Reputation: 1047

XOR very big List with its rotation

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

Answers (3)

Nf4r
Nf4r

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

Pierce Darragh
Pierce Darragh

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

juanpa.arrivillaga
juanpa.arrivillaga

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

Related Questions