Most elegant way to find the position of the odd one out

Viewed 450

I have a list of 3 strings, two of which are always equal. I want to find the odd one out. The problems sound super simple but I haven't been able to find a truly elegant way to do it.

For example, the list, lst = ['foo', 'bar', 'foo'], should return 1. The way I am currently doing it is this:

f = lambda x, y, z: {(0, 0): 0, (0, 1): 1}.get((x == y, x == z), 2)
ans = f(*lst)

Is there a better way here?

3 Answers

You could look for the first occurrence of the last value:

ans = (1, 0, 2)[lst.index(lst[2])]

Or if you're ok with index -1 instead of 2:

ans = 1 - lst.index(lst[2])

A simple method, though not very efficient:

odd_one_out = min(lst, key=lst.count)

To get the index:

odd_one_out_index = min(enumerate(lst), key=lambda i: lst.count(i[1]))[0]

This finds how often every element appears in the list, then selects the one with the lowest count. Note the O(N^2) efficiency though.

What about

0 if lst[1] == lst[2] else 1 if lst[0] == lst[2] else 2
Related