The fastest way to find common elements at the beginning of 2 python lists? -


what fastest way find common elements @ beginning of 2 python lists? coded using loop think writing list comprehensions faster... unfortunately don't know how put break in list comprehension. code wrote:

import datetime  list1=[1,2,3,4,5,6] list2=[1,2,4,3,5,6]  #this "for loop" version, , takes 60 ms on machine start=datetime.datetime.now() out=[]     (e1, e2) in zip(list1, list2):     if e1 == e2:         out.append(e1)     else:         break end=datetime.datetime.now() print out print "execution time: %s ms" % (float((end - start).microseconds) / 1000)  #this list-comprehension version, takes 15 ms run, #but unfortunately returns wrong result because can't break loop. start=datetime.datetime.now() out = [ e1 (e1, e2) in zip(list1, list2) if e1 == e2 ] end=datetime.datetime.now() print out print "execution time: %s ms" % (float((end - start).microseconds) / 1000) 

are there solutions without list comprehensions?

>>> operator import ne >>> itertools import count, imap, compress >>> list1[:next(compress(count(), imap(ne, list1, list2)), 0)] [1, 2] 

timings:

from itertools import * operator import ne  def f1(list1, list2, enumerate=enumerate, izip=izip):     out = []     out_append = out.append     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 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     = 0     end = min(len(list1), len(list2))     while < end , 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     i, e in enumerate(list1):         if list2[i] != e:             return list1[:i]     return list1[:]  def f6(list1, list2, enumerate=enumerate):     result = []     append = result.append     i,e in enumerate(list1):         if list2[i] == e:             append(e)             continue         break     return result   timeit import timeit list1 =[1,2,3,4,5,6];list2=[1,2,4,3,5,6] sol = f3(list1, list2)  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] timeit customized 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 solution @thijsvandien fastest, comes close second still functional style ;)


but numpy wins (you should use numpy things this)

>>> import numpy 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 faster numpy solution shows how fast is.


Comments

Popular posts from this blog

.htaccess - First slash is removed after domain when entering a webpage in the browser -

Automatically create pages in phpfox -

c# - Farseer ContactListener is not working -