Python: find first inconsistency in two lists

Given two lists of the same length, how can you effectively find the first position where the corresponding elements of these lists are not equal? Basically, I need either an index or two unequal elements.

I am wondering if there is a concise "Python" solution without explicit iteration over the lists.

+4
source share
5 answers

You cannot avoid iterating over lists, but you can do it with understanding and get an elegant solution:

next( (idx, x, y) for idx, (x, y) in enumerate(zip(list1, list2)) if x!=y ) 

If you like something less single-line, you can break it down like this

 coupled_idx = enumerate(zip(list1, list2)) res = next( idx for idx, (x, y) in coupled_idx if x!=y ) 

EDIT:

as an addition, if you need to check the case where the two lists can be completely equal, you can add a second parameter to the next function, which tells it what it returns if the index is not found. The most common option is to return None:

 coupled_idx = enumerate(zip(list1, list2)) res = next( (idx for idx, (x, y) in coupled_idx if x!=y), None ) 

Note that you need to enclose the generator expression between the brackets, because this is not the only function argument in this call.

To add a bit of fun, you can also ask the nth other pair by linking the expressions. For example, this gives you all pairs up to the fifth (filling None if the pair is absent)

 coupled_idx = enumerate(zip(list1, list2)) coupler = (idx for idx, (x, y) in coupled_idx if x!=y) res = [ next(coupler, None) for _ in range(5) ] 

EDIT2:

Such a solution actually creates a copy of both lists through a zip function. If you need to avoid this, you can use the izip function from the itertools module.

And about the fun part, you can only select solution certificates using the islice function from the same module

+3
source
 >>> from operator import eq >>> a = [1, 2, 4, 3] >>> b = [1, 2, 3, 4] >>> map(eq, a, b).index(False) 2 
+2
source
 In [1]: l1=[1,2,3] In [2]: l2=[1,4,5] In [4]: next(i for i, (el1, el2) in enumerate(zip(l1, l2)) if el1 != el2) Out[4]: 1 

Here 1 is the first index, where l1 and l2 are different.

0
source

Try the following:

 next(i for i, (el1,el2) in enumerate(zip(li1,li2)) if el1 != el2) 

Or is it an equivalent function:

 def first_diff(li1, li2): for i, (el1,el2) in enumerate(zip(li1,li2)): if el1 != el2: return i return False 

Example

 >>> li1 = range(32) >>> li2 = range(32) >>> li2[10] = 2 >>> next(i for i, (el1,el2) in enumerate(zip(li1,li2)) if el1 != el2) 10 >>> first_diff(li1, li2) 10 
0
source
 >>> from itertools import dropwhile >>> a = [1, 2, 4, 3] >>> b = [1, 2, 3, 4] >>> next(dropwhile(lambda x: x[0] == x[1], zip(a, b))) (4, 3) 
0
source

All Articles