Search code examples
pythonlistfunctionfor-loop

Identify the list that is the odd one out, and find its index from given lists


I am given a list of lists that contains exactly one list that is different from the others.

I tried to solve that with this code:

a = [[1, -2], [1, -2], [1,6], [1, -2], [1, -2]]
     
def find_idx(lists):
     for i in range(len(lists)-1):
          diff = np.array(lists[0])-np.array(lists[i+1])
          for k in diff:
               if k != 0:
                    print(i+1)
find_idx(a)

The above function works well for most inputs, but when the odd one out is at index 0, it returns the wrong result.

For example, with this input:

(lists = [[1, 6],[1, -2], [1, -2], [1, -2], [1, -2]])

I get all indices printed, except the one that I really should get (0).

How can I fix my function so it also works when the differing list sits at index 0?


Solution

  • Your code assumes that lists[0] is the "normal" value (list) that repeats, since you compare any other element with it in your diff expression. But if you find that the entry at index 1 is different from the one at index 0, you cannot yet know which one is the odd one out. You need to make an additional comparison in that case with yet another element from the list (for example the last one).

    Not your question, but:

    • you don't need numpy or that diff expression to compare two lists of integers. In Python you can just compare such lists with ==.

    • A function is more useful when it doesn't print the result, but returns it.

    Here I take the last entry as reference value, and if the very first one happens to be different, there are two possibilities: either the first one is the odd one, or the last. A comparison with the second entry can make the distinction:

    def find_idx(lists):
        reflist = lists[-1]
        for i, lst in enumerate(lists):
            if lst != reflist:
                # when i == 0 we don't have enough information yet: make another comparison
                if i == 0 and lists[1] != reflist:
                    return len(lists) - 1
                return i
        return -1
    

    Example call:

    a = [[0, 6], [1, -2], [1, -2], [1, -2], [1, -2], [1, -2]]
    i = find_idx(a)
    print(i)  # 0