Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Python, efficiently determine if two lists are shifted copies of one another

What's the most efficient (in time) way of checking if two relatively short (about 3-8 elements) lists are shifted copies of one another? And if so, determine and return the offset?

Here is the example code and output I'd like:

>>> def is_shifted_copy(list_one, list_two):
>>>     # TODO
>>>
>>> is_shifted_copy([1, 2, 3], [1, 2, 3])
0
>>> is_shifted_copy([1, 2, 3], [3, 1, 2])
1
>>> is_shifted_copy([1, 2, 3], [2, 3, 1])
2
>>> is_shifted_copy([1, 2, 3], [3, 2, 1])
None
>>> is_shifted_copy([1, 2, 3], [1])
None
>>> is_shifted_copy([1, 1, 2], [2, 1, 1])
1

Lists may have duplicate entries. If more than one offset is valid, return any offset.

like image 341
devtk Avatar asked Mar 14 '13 16:03

devtk


People also ask

How do you compare two lists efficiently in Python?

Python collection.counter() method can be used to compare lists efficiently. The counter() function counts the frequency of the items in a list and stores the data as a dictionary in the format <value>:<frequency>. If two lists have the exact same dictionary output, we can infer that the lists are the same.

How do I compare two lists to find differences in Python?

The difference between two lists (say list1 and list2) can be found using the following simple function. By Using the above function, the difference can be found using diff(temp2, temp1) or diff(temp1, temp2) . Both will give the result ['Four', 'Three'] .

How do you check if two lists share the same element in Python?

Using traversal in two lists, we can check if there exists one common element at least in them. While traversing two lists if we find one element to be common in them, then we return true. After complete traversal and checking, if no elements are same, then we return false.

How do you check if two lists are circularly identical in Python?

Using traversal, we have to double the given list. Check for any x(0<=n) to any x+n and compare with list2 to see if the list1 and list2 are same, if both are same then the list2 is circularly identical.


1 Answers

here's a simple iterator version that does the job in 2n iterations (n being the length of list)

import itertools

def is_shifted_copy(list1, list2):

    if len(list1) != len(list2):
        return False

    iterator = iter(list2)

    for i, item in enumerate(itertools.chain(list1, list1)):
        try:
            if item == iterator.next():
                continue
            else:
                iterator = iter(list2)
        except StopIteration:
            return i - len(list2)

    else:
        return False


print is_shifted_copy([1, 2, 3], [1, 2, 3]) #0
print is_shifted_copy([1, 2, 3], [3, 1, 2]) #2
print is_shifted_copy([1, 2, 3], [3, 2, 1]) #False
print is_shifted_copy([1, 2, 3], [2, 3, 1]) #1
print is_shifted_copy([1, 1, 2], [2, 1, 1]) #2
print is_shifted_copy([1, 2, 3], [1]) #False
print is_shifted_copy([1, 2, 1], [2, 1, 1]) #1
print is_shifted_copy([1, 1, 1], [1, 1, 1]) #0

and from your specification,

shouldn't is_shifted_copy([1, 1, 2], [2, 1, 1]) return 2?

like image 99
thkang Avatar answered Sep 29 '22 07:09

thkang