>>> from operator import ne >>> from itertools import count, imap, compress >>> list1[:next(compress(count(), imap(ne, list1, list2)), 0)] [1, 2]
Timings:
from itertools import * from operator import ne def f1(list1, list2, enumerate=enumerate, izip=izip): out = [] out_append = out.append for e1, e2 in izip(list1, list2): if e1 == e2: out_append(e1) else: break return out def f2(list1, list2, list=list, takewhile=takewhile, izip=izip): return [i for i, j in takewhile(lambda (i,j):i==j, izip(list1, list2))] def f3(list1, list2, next=next, compress=compress, count=count, imap=imap, ne=ne): return list1[:next(compress(count(), imap(ne, list1, list2)), 0)] def f4(list1, list2): out = [] out_append = out.append i = 0 end = min(len(list1), len(list2)) while i < end and list1[i]==list2[i]: out_append(list1[i]) i+=1 return out def f5(list1, list2, len=len, enumerate=enumerate): if len(list1) > len(list2): list1, list2 = list2, list1 for i, e in enumerate(list1): if list2[i] != e: return list1[:i] return list1[:] def f6(list1, list2, enumerate=enumerate): result = [] append = result.append for i,e in enumerate(list1): if list2[i] == e: append(e) continue break return result from timeit import timeit list1 =[1,2,3,4,5,6];list2=[1,2,4,3,5,6] sol = f3(list1, list2) for func in 'f1', 'f2', 'f3', 'f4', 'f5', 'f6': assert eval(func + '(list1, list2)') == sol, func + " produces incorrect results" print func print timeit(stmt=func + "(list1, list2)", setup='from __main__ import *')
f1 1.52226996422 f2 2.44811987877 f3 2.04677891731 f4 1.57675600052 f5 1.6997590065 f6 1.71103715897
For list1=[1]*100000+[1,2,3,4,5,6]; list2=[1]*100000+[1,2,4,3,5,6] list1=[1]*100000+[1,2,3,4,5,6]; list2=[1]*100000+[1,2,4,3,5,6] with timeit set to 100 timings, timeit(stmt=func + "(list1, list2)", setup='from __main__ import list1, list2, f1,f2,f3,f4', number=1000)
f1 14.5194740295 f2 29.8510630131 f3 12.6024291515 f4 24.465034008 f5 12.1111371517 f6 16.6644029617
So this solution from @ThijsvanDien is the fastest, it comes second, but I still like its functional style;)
But numpy always wins (you should always use numpy for such things)
>>> import numpy as np >>> a, b = np.array([1,2,3,4,5,6]), np.array([1,2,4,3,5,6]) >>> def f8(a, b, nonzero=np.nonzero): return a[:nonzero(a!=b)[0][0]] >>> f8(a, b) array([1, 2]) >>> timeit(stmt="f8(a, b)", setup='from __main__ import *') 6.50727105140686 >>> a, b = np.array([1]*100000+[1,2,3,4,5,6]), np.array([1]*100000+[1,2,4,3,5,6]) >>> timeit(stmt="f8(a, b)", setup='from __main__ import *', number=1000) 0.7565150260925293
There may be a faster numpy solution, but this shows how fast it works.