2

I'm trying to run some functions by mapping them to keys in my lookup table. I have a list, lis and I traverse it and checks if some of the values in my list are the same as the keys in my lookup table. If they are I'd like to run the function according to the key. When I try to run the below it prints them all 3, which I don't understand.

as it should only print 1 and 2 in my eyes.

ops1 = {


        "1": print("1"),
        "2": print("2"),
        "4": print("4")
}

lis = [1, 2, 3]

for x in range(0, len(lis)-1):
    if (lis[x] in ops1.keys()):
        ops1.get(x)
JonCode
  • 241
  • 1
  • 8
  • 20

2 Answers2

3

Let's go through it line by line.

ops1 = {
        "1": print("1"), # this value is actually the value returned by print
        "2": print("2"),
        "4": print("4")
} # when the dictionary is created, everything in it is evaluated,
# so it executes those print calls
# that's why you see all three printed

lis = [1, 2, 3]

for x in range(0, len(lis)-1): # this includes 0 and 1
    if (lis[x] in ops1.keys()): # lis[0] is 1 and lis[1] is 2
        ops1.get(x) # look for 0 and then 1 in the dictionary

Now let's fix it.

ops1 = {
        "1": lambda: print("1"), # this value is now a FUNCTION, which you can call later
        "2": lambda: print("2"),
        "4": lambda: print("4")
} # when the dictionary is created, everything in it is evaluated, but the functions are not called

lis = [1, 2, 3]

for x in range(len(lis)): # goes through 0, 1, and 2
    if lis[x] in ops1: # lis[0] is 1, lis[1] is 2, lis[2] is 3
        ops1.get(str(lis[x]), print)() # look for '1', '2', and '3',
                                       # then call their values

You could improve that last loop like this:

for x in lis:
    ops1.get(str(x), print)()

So, first we look up the key '1'. That corresponds to a function. Then we call the function. This prints the string '1\n'. Then we look up the key '2'. That corresponds to a function. Then we call the function. This prints the string '2\n'. Then we look up the key '3'. This is not present in the dictionary, so it returns a default function. Then we call this default function. This prints the string '\n'.

TigerhawkT3
  • 48,464
  • 6
  • 60
  • 97
  • Thanks alot for a clear explanation! Very appreciated. I've got something to work with now, thank you! – JonCode Oct 18 '15 at 07:54
1

Try this(roughly)

Problem is you are assigning the results of calling print i.e. None, to your lookup table. You want to assign the function definition instead, wo calling it. Then call the lookedup function in your loop.

def print1():
    print(1)

Ops = {
"1" : print1,
"2" : another_func,
...

}

for key in ["1","2","3"]:
    ops[key]()
JL Peyret
  • 10,917
  • 2
  • 54
  • 73