1

I know Java and C and I used to use Switch statements, but there aren't in python.

I see many ways of use if-elif-else to remplace, but any that remplace completly.

Example of code that I want remplace.

switch(expression) {
   case a:
       doA();
   case b:
       doB();
   case c:
       doC();
       break;
   case d:
   case e:
       doDE()
       break;
   case f:
   case g:
       doFG():
   case h:
       doH();
       break;
   case i:
       doI();
   default:
       foo();
       break;
}

As you can see not all case are follow by break, and there is code between some cases that only executed with one case, but there is also common code that is executed in both case.

I see a many ways, but any that allow this at same time. And I think this is the real diference between if-elif-else, and switch-case.

So there is any way of do this will be great, or it's only posible with repeted functions calls and complex if with all posibilities?.

Thank you.

gilch
  • 10,813
  • 1
  • 23
  • 28
  • I saw this post: https://stackoverflow.com/questions/60208/replacements-for-switch-statement-in-python, but I dont find any solution that give me a complete solution – Miguel Angel Alvarez Rodriguez May 02 '18 at 23:58
  • Break out the cases into functions, put the functions into a dictionary. Have functions that are supposed to "fall through" simply cal the next one. More trouble than it's worth, probably. – kindall May 03 '18 at 00:01
  • Not once in my life have I ever needed such a massive `switch` or `if` statement. Are you sure you're not doing something wrong in your code? Can you give us some context so that we can suggest alternative solutions? – Aran-Fey May 03 '18 at 00:08
  • It has no contex, I would like case statement and I want to know if there was a solution that allow to do all combination of case allow. Thank you all, I think the best solution is given by glich. – Miguel Angel Alvarez Rodriguez Oct 23 '18 at 03:24

2 Answers2

1

The switch statement is considered harmful. That's probably why Python doesn't have it. The fallthrough behavior is a major source of bugs in C code. It's easy to forget a break; That's why C# disallows it--you'd have to use an explicit goto instead. It's the same in Python's dict of functions approach. You put in a call to the next function. "Explicit is better than implicit".

The easiest way to make a dict of functions (with identifier keys) is with a class declaration.

class switch:
    def a():
        print('a')
        switch.b()
    def b():
        print('b')
        switch.c()
    def c():
        print('c')
    def d():
        switch.e()
    def e():
        print('de')
    def f():
        switch.g()
    def g():
        print('fg')
    def h():
        print('h')
    def i():
        print('i')
        switch.default()
    def default():
        print('foo')

Use it like so.

>>> expression = 'a'
>>> getattr(switch, expression, 'default')()
a
b
c

You can also extract the __dict__ attr if you want an actual dict.

>>> switch.__dict__.get('e', 'default')()
de

You can be similarly explicit with if statements.

def switch(case)
    if case == a:
        doA()
        case = b
    if case == b:
        doB()
        case = c
    if case == c:
        doC()
        return
    if case == d:
        case = e
    if case == e:
        doDE()
        return
    if case == f:
        case = g
    if case == g:
        doFG()
        case = h
    if case == h:
        doH()
        return
    if case == i:
        doI()
    foo()

If you're worried about side effects changing the condition or if the conditions are more complex than simple equality and you don't want to repeat them, you can use a helper variable instead of reassigning case.

def switch(case):
    fall = False
    if case == a:
        doA()
        fall = True
    if fall or case == b:
        doB()
        fall = True
    if fall or case == c:
        doC()
        return
    if case == d:
        fall = True
    if fall or case == e:
        doDE()
        return
    if case == f:
        fall = True
    if fall or case == g:
        doFG()
        fall = True
    if fall or case == h:
        doH()
        return
    if case == i:
        doI()
    foo()
gilch
  • 10,813
  • 1
  • 23
  • 28
  • Thank you. I saw many complex solution but any as simple and complet like that, I want to avoid to call explicit the next "case" if I have no break, but it easy to understand and I think this is a good way to simulate the case syntaxis. – Miguel Angel Alvarez Rodriguez Oct 23 '18 at 03:22
1

The if statement can do any condition at all. You just have to be a little more explicit.

def switch(case):
    if case in 'a':
        doA()
    if case in 'ab':
        doB()
    if case in 'abc':
        doC()
        return
    if case in 'de':
        doDE()
        return
    if case in 'fg':
        doFG()
    if case in 'fgh':
        doH()
        return
    if case in 'i':
        doI()
    foo()
gilch
  • 10,813
  • 1
  • 23
  • 28
  • I know with a If you can do any case, but I saw many complicate ways to simulate the case syntaxis but all always have to do something extra or not allow exacly the same that the "case" statement. I think the best solution I find by now is use a class and call in the end of a case the next one if I want not to break. – Miguel Angel Alvarez Rodriguez Oct 23 '18 at 03:20