29

I am trying to check each index in an 8 digit binary string. If it is '0' then it is 'OFF' otherwise it is 'ON'.

Is there a more concise way to write this code with a switch-like feature?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
AME
  • 5,234
  • 23
  • 71
  • 81
  • 5
    Are you trying to do [{'0':'Off', '1':'On'}.get(b) for b in "01101101"] – joeforker Sep 15 '09 at 20:47
  • The canonical is *[Replacements for switch statement in Python?](https://stackoverflow.com/questions/60208/replacements-for-switch-statement-in-python/60211#60211)* [sic]. It also has the switch statement introduced with Python 3.10 (2021). – Peter Mortensen Oct 05 '21 at 11:24

6 Answers6

41

No, it doesn't. When it comes to the language itself, one of the core Python principles is to only have one way to do something. The switch is redundant to:

if x == 1:
    pass
elif x == 5:
    pass
elif x == 10:
    pass

(without the fall-through, of course).

The switch was originally introduced as a compiler optimization for C. Modern compilers no longer need these hints to optimize this sort of logic statement.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Soviut
  • 88,194
  • 49
  • 192
  • 260
  • 19
    Anyone who thinks Python "only has one way to do something" is very confused. – Glenn Maynard Sep 15 '09 at 22:49
  • Fixed. I guess I could have claimed that it was python-esque pseudo-code, hehe. – Soviut Sep 15 '09 at 22:49
  • 20
    @Glenn Maynard: There may be more than one way to do it, but "There should be one -- and preferably only one -- **obvious** way to do it", per PEP 20 ("The Zen of Python"). – Daniel Pryden Sep 15 '09 at 22:53
  • 6
    I believed `switch`'s purpose was to tell the compiler to build a jump table? (I know current compilers don't need this.) – Bastien Léonard Sep 15 '09 at 22:54
  • 1
    @Glenn do understand that while there are many redundant python modules, the actual core language has little in the way of redundant functionality. – Soviut Sep 16 '09 at 02:32
  • 8
    Although that way may not be obvious at first unless you're Dutch. – Stefano Borini Sep 16 '09 at 13:09
  • @Soviut: by "angle brackets" I presume you meant "curly braces" (or equivalent, by locale; `{}` instead of `<>`)? – Chris Morgan Nov 24 '10 at 07:39
  • 1
    A switch statement was introduced [with Python 3.10 (2021)](https://stackoverflow.com/questions/60208/replacements-for-switch-statement-in-python/60211#60211). – Peter Mortensen Oct 05 '21 at 11:12
13

Try this instead:

def on_function(*args, **kwargs):
    # do something

def off_function(*args, **kwargs):
    # do something

function_dict = { '0' : off_function, '1' : on_function }

for ch in binary_string:
   function_dict[ch]()

Or you could use a list comprehension or generator expression if your functions return values:

result_list = [function_dict[ch]() for ch in binary_string]
Jeff
  • 14,831
  • 15
  • 49
  • 59
8

As of Python 3.10.0 (alpha6 released March 30, 2021) there is an official true syntactic equivalent now!


digit = 5
match digit:
    case 5:
        print("The number is five, state is ON")
    case 1:
        print("The number is one, state is ON")
    case 0:
        print("The number is zero, state is OFF")
    case _:
        print("The value is unknown")

I've written up this other Stack Overflow answer where I try to cover everything you might need to know or take care of regarding match.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
fameman
  • 3,451
  • 1
  • 19
  • 31
0

else-if is bad practice, since they are unsafe when they get too long, and involve unnecessary conditional branching (maybe affecting compiler / caching).

Try this...

class Functions():
    @staticmethod
    def func():
        print("so - foo")
    @staticmethod
    def funcWithArgs(junk):
        print(junk, "foo")

# Fill in your cases here...
cases = {
    "a": Functions.func,
    "b": Functions.funcWithArgs,
    "c": Functions.funcWithArgs
}

def switch(ch, cases, *args):
    try:
        len(*args)  # Empty arguments
    except TypeError:
        return cases[ch]()
    return cases[ch](*args)

# Try out your switch...
switch("a", cases)  # "so - foo"
switch("b", cases, "b -")  # "b - foo"
switch("c", cases, "c -")  # "c - foo"
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jason
  • 1,974
  • 24
  • 19
0

A switch statement is a very useful construction in the C language. In Python it can be in most cases replaced with dictionaries.

I think that switch statements are also very useful when implementing state machines, and Python does not have a replacement for this. It usually leads to a "bad" programming style to a long function. But it is the switch statement, that divides the state function to little pieces. In Python, the if - elif construction must be used. Most uses of a switch statement can be replaced in a more elegant way, some in a little bit less elegant way.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Pavel S.
  • 19
  • 2
0

since python 3.10 there is match-case statement `

def f(x):
    match x:
        case 'a':
            return 1
        case 'b':
            return 2
        case _:        
            return 0   # 0 is the default case if x is not found

`

Sid
  • 71
  • 1
  • 1
  • 9