Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Switch in Python

I have tried making a switch like statement in python, instead of having a lot of if statements.

The code looks like this:

def findStuff(cds):
    L=[]
    c=0
    for i in range(0, len(cds), 3):
        a=differencesTo(cds[i:i+3])
        result = {
            a[2][0]==1: c=i+1,
            a[2][1]==1: c=i+2,
            a[2][2]==1: c=i+3,
            a[1]==1: L.append((cds[i:i+3], a[0], c))
        } 
    return L

My problem is, that this does not work. (Works with if statements, but this would in my opinion be more pretty).

I have found some examples of switches in Python, and they follow this structure. Can anyone help me?

like image 766
X-Pender Avatar asked Jan 17 '12 13:01

X-Pender


4 Answers

(a) I fail to see what is wrong with if...elif...else

(b) I assume that python does not have a switch statement for the same reason that Smalltalk doesn't: it's almost completely redundant, and in the case where you want to switch on types, you can add an appropriate method to your classes; and likewise switching on values should be largely redundant.

Note: I am informed in the comments that whatever Guido's reason for not creating a switch in the first place, PEPs to have it added were rejected on the basis that support for adding such a statement is extremely limited. See: http://www.python.org/dev/peps/pep-3103/

(c) If you really need switching behaviour, use a hashtable (dict) to store callables. The structure is:

switch_dict = {
    Foo: self.doFoo,
    Bar: self.doBar,
    }

func = switch_dict[switch_var]
result = func() # or if they take args, pass args
like image 93
Marcin Avatar answered Nov 01 '22 15:11

Marcin


There's nothing wrong with a long if:

if switch == 'case0':
   do_case0()
elif switch == 'case1':
   do_case1()
elif switch == 'case2':
   do_case2()
...

If that's too long winded, or if you have a lot of cases, put them in a dictionary:

switch = {'case0': do_case0, 'case1': do_case1, 'case2': do_case2, ...}
switch[case_variable]()
// Alternative:
(switch[case_variable]).__call__()

If your conditions are a bit more complex, you need to think a little about your data structures. e.g.:

switch = {
    (0,21): 'never have a pension',
    (21,50): 'might have a pension',
    (50,65): 'definitely have a pension',
    (65, 200): 'already collecting pension'
}
for key, value in switch.items():
    if key[0] <= case_var < key[1]:
        print(value)
like image 28
snim2 Avatar answered Nov 01 '22 15:11

snim2


Other ans are suitable for older version of python. For python v3.10+ you can use match/case which is more powerful than general switch/case construct.

def something(val):
    match val:
        case "A":
            return "A"
        case "B":
            return "B"
        case "C":
            return "C"
        case _:
            return "Default"

something("A")
like image 2
k33da_the_bug Avatar answered Nov 01 '22 16:11

k33da_the_bug


Assignment in Python is a statement, and cannot be a part of expression. Also, using literal in this way evaluates everything at once, which is probably not what you want. Just use ifs, you won't gain any readability by using this.

like image 1
Cat Plus Plus Avatar answered Nov 01 '22 15:11

Cat Plus Plus