2

I am trying to implement a function by using the following example from Replacements for switch statement in Python:

def f(x):
    return {
        '+': (lambda x: x[1] + x[2]),
        '-': (lambda x: x[1] - x[2])
    }[x[0]]

print(f(["+",2,3])) #Output should be 5. 

f(["-", 4, 1]) # Output should be 3.

I am clearly doing something wrong. Maybe someone has even a better suggestion for this?

EDIT:

What if I wanted to save the output of the lambda in a list and then return it?

For example:

def f(x, output):
    return {
        '+': (lambda x: x[1] + x[2]),
        '-': (lambda x: x[1] - x[2])
    }[x[0]]

output = [10, 20, 30, 40]

# to 2nd element in output list we add the last element in the list
print(f(["+",2,3], output)) #Output should be output = [10, 20, 33, 40]

output = [10, 20, 30, 40]
f(["-", 1, 100]) # Output should be [10, 120, 30, 40].
jpp
  • 159,742
  • 34
  • 281
  • 339
Gabriele
  • 737
  • 2
  • 8
  • 20

2 Answers2

6

Remember to actually apply the mapped function to the variable:

def f(x):
    return {
        '+': (lambda x: x[1] + x[2]),
        '-': (lambda x: x[1] - x[2])
    }[x[0]](x)

print(f(["+",2,3]))  # 5 

This is a more flexible version:

d = {'+': (lambda x: x[1] + x[2]),
     '-': (lambda x: x[1] - x[2])}

def calculator(x, d):
    return d[x[0]](x)

print(calculator(["+",2,3], d))  # 5

An even better idea is to use your dispatcher to only store operations.

See @WillemVanOnsem's answer for more details.

jpp
  • 159,742
  • 34
  • 281
  • 339
0

Your dictionary maps a string to a function, not the result of that function, that is where the lambda comes in. You can solve it in two ways: or you calculate the results directly, or you call the function at the end.

def f(x):
    return {
        '+': (lambda: x[1] + x[2]),
        '-': (lambda: x[1] - x[2])
    }[x[0]]()  # calling the function!

print(f(["+",2,3])) #Output should be 5. 

f(["-", 4, 1]) # Output should be 3.

You can however also declare functions, and pass arguments to it. This will make it more flexible as well, since for instance a hypothetical f(["sin", 1.2]) has only a single argument. We can for instance construct a dictionary like:

from operator import add, sub
from math import sin

FUNC_DICT = {
    '+': add,
    '-': sub,
    'sin': sin
}

Then our f looks like:

def f(x):
    return FUNC_DICT[x[0]](*x[1:])

So we call the function with the rest of the elements in the list.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555