Skip to content

Instantly share code, notes, and snippets.

@paul-butcher
Created June 17, 2021 15:16
Show Gist options
  • Save paul-butcher/7dd84fcbd71e3c8f5100481c14a5993d to your computer and use it in GitHub Desktop.
Save paul-butcher/7dd84fcbd71e3c8f5100481c14a5993d to your computer and use it in GitHub Desktop.
A demonstration of using a dict of callables instead of a chain of if/elif/elif branches
from timeit import timeit
import string
# If you have a chain of if and elif like this
# that you then use to decide a particular
# course of action
def ifelif(arg1, arg2):
if arg1 == 'hello':
return 'hi ' + arg2
elif arg1 == 'namaskara':
backwards_name = str(reversed(arg2))
return 'susvagata ' + backwards_name
elif arg1 == 'may the force be with you':
return 'and also with you'
raise ValueError('unknown greeting')
# You can instead create a dict, keyed on the greeting, with callables as the value.
def backwards_welcome(name):
backwards_name = str(reversed(name))
return 'susvagata ' + backwards_name
# The dict should be created outside of the function, either as a member of the object, class or module.
greetings = {
'hello': lambda x: 'hi ' + x,
# If it undesirable to use lambda (e.g. side-effects, too big, whatever)
# define a function the old fashioned way.
'namaskara': backwards_welcome,
# The callables must all have the same number of arguments, even if you don't use them
# or you can use *args,**kwargs to allow variable args.
'may the force be with you': lambda _: 'and also with you',
}
# This makes the function look like this instead:
def by_dict(arg1, arg2):
try:
return greetings[arg1](arg2)
except KeyError:
raise ValueError('unknown greeting')
# At this scale, it doesn't make any difference to performance,
# So the choice is purely cosmetic, and subject to personal preference.
print('by ifs, first branch')
print(timeit(lambda: ifelif('hello', 'paul')))
print('by dict, first entry')
print(timeit(lambda: by_dict('hello', 'paul')))
print('by ifs, last branch')
print(timeit(lambda: ifelif('may the force be with you', 'paul')))
print('by dict, last entry')
print(timeit(lambda: by_dict('may the force be with you', 'paul')))
def bigif(arg):
if(arg is None): return None
elif(arg =="a"): return "hello"
elif(arg =="b"): return "hello"
elif(arg =="c"): return "hello"
elif(arg =="d"): return "hello"
elif(arg =="e"): return "hello"
elif(arg =="f"): return "hello"
elif(arg =="g"): return "hello"
elif(arg =="h"): return "hello"
elif(arg =="i"): return "hello"
elif(arg =="j"): return "hello"
elif(arg =="k"): return "hello"
elif(arg =="l"): return "hello"
elif(arg =="m"): return "hello"
elif(arg =="n"): return "hello"
elif(arg =="o"): return "hello"
elif(arg =="p"): return "hello"
elif(arg =="q"): return "hello"
elif(arg =="r"): return "hello"
elif(arg =="s"): return "hello"
elif(arg =="t"): return "hello"
elif(arg =="u"): return "hello"
elif(arg =="v"): return "hello"
elif(arg =="w"): return "hello"
elif(arg =="x"): return "hello"
elif(arg =="y"): return "hello"
elif(arg =="z"): return "hello"
elif(arg =="A"): return "hello"
elif(arg =="B"): return "hello"
elif(arg =="C"): return "hello"
elif(arg =="D"): return "hello"
elif(arg =="E"): return "hello"
elif(arg =="F"): return "hello"
elif(arg =="G"): return "hello"
elif(arg =="H"): return "hello"
elif(arg =="I"): return "hello"
elif(arg =="J"): return "hello"
elif(arg =="K"): return "hello"
elif(arg =="L"): return "hello"
elif(arg =="M"): return "hello"
elif(arg =="N"): return "hello"
elif(arg =="O"): return "hello"
elif(arg =="P"): return "hello"
elif(arg =="Q"): return "hello"
elif(arg =="R"): return "hello"
elif(arg =="S"): return "hello"
elif(arg =="T"): return "hello"
elif(arg =="U"): return "hello"
elif(arg =="V"): return "hello"
elif(arg =="W"): return "hello"
elif(arg =="X"): return "hello"
elif(arg =="Y"): return "hello"
elif(arg =="Z"): return "hello"
bigdict = {k: lambda: 'hello' for k in string.ascii_letters}
# When you have a large set of choices, the dict wins hands down.
print('by ifs, first branch, big selection')
print(timeit(lambda: bigif('A')))
print('by dict, first entry, big_selection')
print(timeit(lambda: bigdict['A']()))
print('by ifs, last branch, big selection')
print(timeit(lambda: bigif('Z')))
print('by dict, last entry, big_selection')
print(timeit(lambda: bigdict['Z']()))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment