0

Here's a piece of code from this question, it's an alternative to a switch statement in Python.

result = {
  'a': lambda x: x * 5,
  'b': lambda x: x + 7,
  'c': lambda x: x - 2
}[value](x)

I'm new to Python and I don't understand what it's doing. So I get that the first part is variable assignment - but what does [value](x) do?

half of a glazier
  • 1,864
  • 2
  • 15
  • 45
  • `[value]` will return the value corresponding to the key `value`. Then `(x)`will call the lambda e expression with param `x` – Abdul Niyas P M Jan 21 '21 at 14:28
  • 1
    Please do not use this. Use an `if` condition – DeepSpace Jan 21 '21 at 14:30
  • @DeepSpace why not? this looks like a pretty nice switch alternative to me – Nullman Jan 21 '21 at 14:40
  • @Nullman Because it adds noise to the code, and has a huge overhead (when compared to what it achieves): creating a dict, 3 functions, hashes `value` and executes one of the functions... for almost no reason, and can be achieved with 3 `elif` branches – DeepSpace Jan 21 '21 at 14:49
  • @Nullman The fact that OP asked this question is a living proof. This question could have been avoided if this was implemented with `if` – DeepSpace Jan 21 '21 at 14:50
  • 1
    it is a `dict` storing function as value. so, `dict['a'`] will return a function, and `dict['a'](x)` will execute that function – Moinuddin Quadri Jan 21 '21 at 14:57

2 Answers2

1

The part between the braces {} defines a dictionary, with keys of 'a', 'b' and 'c'. The values for those keys are lambdas, which are anonymous functions (functions with no name). Each lambda defines a mapping of x to a function of x, with three different mappings, one for each key.

'[value]' looks up value in the dictionary. So if value = 'b', it will return lambda x: x + 7. This x is not related to the x in (x). The lambdas could have been defined as lambda y: y + 7 for example.

'(x)' then applies that lambda to whatever the value of x is.

So if value = 'b' and x = 8, the expression above will give 15 as the answer.

closetCoder
  • 1,064
  • 10
  • 21
1

It is a convoluted way to replicate a switch statement. A cleaner way would be to define a helper function that will let you use a more straightfoward expression of what's going on:

def switch(v):yield lambda *c: v in c

Which you could use like this to get the equivalent result:

for case in switch(value):
    if   case('a'): result = x + 5
    elif case('b'): result = x + 7
    elif case('c'): result = x - 2

That is a very simple example which does little more than make the code more legible. When you have more complex or varied things to do in each case, then this switch pattern becomes a lot more valuable. You can also use it in a more C-Like style:

for case in switch(letter):

    if case('a','A'): 
        y = complexCalculation(12,4) 
        result = y + 5
        print(y)
        break

    if case('b','c','d'): 
        z = factorial(y) **2 
        result = z + 5
        print(z)
        break

else: # otherwise (all other cases)
    print("invalid value provided")

        

 
Alain T.
  • 40,517
  • 4
  • 31
  • 51