If I have a function to, for example, check if list1
is a sublist of list2
, which option is better:
Option 1:
Storing local is better because the lookup that python does is faster. It even pays off to store functions locally.
Performance questions are best answered by timing them - you can measure this using timeit:
import timeit
def noTempFunc():
for _ in range(200):
max([1,4,5,6])
def tempFunc():
m = max
for _ in range(200):
m([1,4,5,6])
print(timeit.timeit(noTempFunc, number=1000)) # 0.055301458000030834
print(timeit.timeit(tempFunc, number=1000)) # 0.049811941999905684 : 11% faster
In this case the max()
of the global context only has to be looked up once, and further lookups are done locally which is ~ 11% faster based on these numbers.
It pays up if you use your local m()
multiple times.
In your case it would be sensible to cache the len_list1 = len(list1)
- as it is used lots of time and does not change.
To make it more readable, you can consider:
def isSublist(list1, list2):
"""Checks if list2 is a sublist of list1"""
len_part = len(list2) # reused inside the list comp, only "calulated" once
return any( x == list2 for x in (list1[i:i+len_part]
for i in range(len(list1)-len_part+1) ))
print(isSublist([1,2,3,4],[1]))
print(isSublist([1,2,3,4],[2,3]))
print(isSublist([1,2,3,4],[1,2,4]))
print(isSublist([1,2,3,4],[1,2,3,4]))
Output:
True
True
False
True
Lookups:
Your faster version with cached length as well (based on Scott Mermelstein answer):
def isSublist1a(list1,list2): # cached length as well
l1 = len(list1)
for i in range(len(list2)):
part=list2[i:]
if len(part)
delivers (2 executions):
0.08652938600062043 # cached part
0.08017484299944044 # cached part + cached list1 lenght - slightly faster
0.15090413599955355 # non-cached version
0.8882850420004615 # cached part
0.8294611960000111 # cached part + cached list1 lenght - slightly faster
1.5524438030006422 # non-cached version