# 在Python中replaceswitch语句？

` `def f(x): return { 'a': 1, 'b': 2, }[x]` `

` `def f(x): return { 'a': 1, 'b': 2 }.get(x, 9) # 9 is default if x not found` `

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

` `if x == 'a': # Do the thing elif x == 'b': # Do the other thing if x in 'bc': # Fall-through by not using elif, but now the default case includes case 'a'! elif x in 'xyz': # Do yet another thing else: # Do the default` `

` `class switch(object): value = None def __new__(class_, value): class_.value = value return True def case(*args): return any((arg == switch.value for arg in args))` `

` `while switch(n): if case(0): print "You typed zero." break if case(1, 4, 9): print "n is a perfect square." break if case(2): print "n is an even number." if case(2, 3, 5, 7): print "n is a prime number." break if case(6, 8): print "n is an even number." break print "Only single-digit numbers are allowed." break` `

testing：

` `n = 2 #Result: #n is an even number. #n is a prime number. n = 11 #Result: #Only single-digit numbers are allowed.` `

` `choices = {'a': 1, 'b': 2} result = choices.get(key, 'default')` `

` `// C Language version of a simple 'switch/case'. switch( key ) { case 'a' : result = 1; break; case 'b' : result = 2; break; default : result = -1; }` `

` `choices = {'a': (1, 2, 3), 'b': (4, 5, 6)} (result1, result2, result3) = choices.get(key, ('default1', 'default2', 'default3'))` `

` `class SMTP: def lookupMethod(self, command): return getattr(self, 'do_' + command.upper(), None) def do_HELO(self, rest): return 'Howdy ' + rest def do_QUIT(self, rest): return 'Bye' SMTP().lookupMethod('HELO')('foo.bar.com') # => 'Howdy foo.bar.com' SMTP().lookupMethod('QUIT')('') # => 'Bye'` `

` `class SMTP: # ... def do_UNKNOWN(self, rest): raise NotImplementedError, 'received unknown command' def state_COMMAND(self, line): line = line.strip() parts = line.split(None, 1) if parts: method = self.lookupMethod(parts[0]) or self.do_UNKNOWN if len(parts) == 2: return method(parts[1]) else: return method('') else: raise SyntaxError, 'bad syntax' SMTP().state_COMMAND(' HELO foo.bar.com ') # => Howdy foo.bar.com` `

（原来的方法也被称为`state_COMMAND` ，因为它使用相同的模式来实现一个状态机，即`getattr(self, 'state_' + self.mode)`

` `# The following example is pretty much the exact use-case of a dictionary, # but is included for its simplicity. Note that you can include statements # in each suite. v = 'ten' for case in switch(v): if case('one'): print 1 break if case('two'): print 2 break if case('ten'): print 10 break if case('eleven'): print 11 break if case(): # default, could also just omit condition or 'if True' print "something else!" # No need to break here, it'll stop anyway # break is used here to look as much like the real thing as possible, but # elif is generally just as good and more concise. # Empty suites are considered syntax errors, so intentional fall-throughs # should contain 'pass' c = 'z' for case in switch(c): if case('a'): pass # only necessary if the rest of the suite is empty if case('b'): pass # ... if case('y'): pass if case('z'): print "c is lowercase!" break if case('A'): pass # ... if case('Z'): print "c is uppercase!" break if case(): # default print "I dunno what c was!" # As suggested by Pierre Quentel, you can even expand upon the # functionality of the classic 'case' statement by matching multiple # cases in a single shot. This greatly benefits operations such as the # uppercase/lowercase example above: import string c = 'A' for case in switch(c): if case(*string.lowercase): # note the * for unpacking as arguments print "c is lowercase!" break if case(*string.uppercase): print "c is uppercase!" break if case('!', '?', '.'): # normal argument passing style also applies print "c is a sentence terminator!" break if case(): # default print "I dunno what c was!"` `

` `result = { 'a': obj.increment(x), 'b': obj.decrement(x) }.get(value, obj.default(x))` `

` `func, args = { 'a' : (obj.increment, (x,)), 'b' : (obj.decrement, (x,)), }.get(value, (obj.default, (x,))) result = func(*args)` `

` `class Switch: def __init__(self, value): self._val = value def __enter__(self): return self def __exit__(self, type, value, traceback): return False # Allows traceback to occur def __call__(self, cond, *mconds): return self._val in (cond,)+mconds from datetime import datetime with Switch(datetime.today().weekday()) as case: if case(0): # Basic usage of switch print("I hate mondays so much.") # Note there is no break needed here elif case(1,2): # This switch also supports multiple conditions (in one line) print("When is the weekend going to be here?") elif case(3,4): print("The weekend is near.") else: # Default would occur here print("Let's go have fun!") # Didn't use case for example purposes` `

` `def f(x): try: return { 'a': 1, 'b': 2, }[x] except KeyError: return 'default'` `

` `macro switch(arg1): while True: cont=False val=%arg1% socket case(arg2): if val==%arg2% or cont: cont=True socket socket else: socket break` `

` `a=3 switch(a): case(0): print("Zero") case(1): print("Smaller than 2"): break else: print ("greater than 1")` `

` `a=3 while True: cont=False if a==0 or cont: cont=True print ("Zero") if a==1 or cont: cont=True print ("Smaller than 2") break print ("greater than 1") break` `

` `def first_case(): print "first" def second_case(): print "second" def third_case(): print "third" mycase = { 'first': first_case, #do not use () 'second': second_case, #do not use () 'third': third_case #do not use () } myfunc = mycase['first'] myfunc()` `

` `l = ['Dog', 'Cat', 'Bird', 'Bigfoot', 'Dragonfly', 'Snake', 'Bat', 'Loch Ness Monster'] for x in l: if x in ('Dog', 'Cat'): x += " has four legs" elif x in ('Bat', 'Bird', 'Dragonfly'): x += " has wings." elif x in ('Snake',): x += " has a forked tongue." else: x += " is a big mystery by default." print(x) print() for x in range(10): if x in (0, 1): x = "Values 0 and 1 caught here." elif x in (2,): x = "Value 2 caught here." elif x in (3, 7, 8): x = "Values 3, 7, 8 caught here." elif x in (4, 6): x = "Values 4 and 6 caught here" else: x = "Values 5 and 9 caught in default." print(x)` `

` `Dog has four legs Cat has four legs Bird has wings. Bigfoot is a big mystery by default. Dragonfly has wings. Snake has a forked tongue. Bat has wings. Loch Ness Monster is a big mystery by default. Values 0 and 1 caught here. Values 0 and 1 caught here. Value 2 caught here. Values 3, 7, 8 caught here. Values 4 and 6 caught here Values 5 and 9 caught in default. Values 4 and 6 caught here Values 3, 7, 8 caught here. Values 3, 7, 8 caught here. Values 5 and 9 caught in default.` `

` `switch ...parameter... case p1: v1; break; case p2: v2; break; default: v3;` `

` `(lambda x: v1 if p1(x) else v2 if p2(x) else v3)` `

` `(lambda x: v1 if p1(x) else v2 if p2(x) else v3)` `

python版本不是一个语句，而是一个expression式，它的值是一个值。

` `result = { 'a': lambda x: x * 5, 'b': lambda x: x + 7, 'c': lambda x: x - 2 }.get(whatToUse, lambda x: x - 22)(value)` `

` `.get('c', lambda x: x - 22)(23)` `

` `.get('xxx', lambda x: x - 22)(44)` `

` `# simple case alternative some_value = 5.0 # this while loop block simulates a case block # case while True: # case 1 if some_value > 5: print ('Greater than five') break # case 2 if some_value == 5: print ('Equal to five') break # else case 3 print ( 'Must be less than 5') break` `

` `In [2]: result = { ...: 'a': lambda x: 'A', ...: 'b': lambda x: 'B', ...: 'c': lambda x: 'C' ...: } ...: result['a']('a') ...: Out[2]: 'A' In [3]: result = { ...: 'a': lambda : 'A', ...: 'b': lambda : 'B', ...: 'c': lambda : 'C', ...: None: lambda : 'Nothing else matters' ...: } ...: result['a']() ...: Out[3]: 'A'` `

` `if something: return "first thing" elif somethingelse: return "second thing" elif yetanotherthing: return "third thing" else: return "default thing"` `

` `def f(x): return 1 if x == 'a' else\ 2 if x in 'bcd' else\ 0 #default` `

` `def switch1(value, options): if value in options: options[value]()` `

` `def sample1(x): local = 'betty' switch1(x, { 'a': lambda: print("hello"), 'b': lambda: ( print("goodbye," + local), print("!")), })` `

` `def switch(value, *maps): options = {} for m in maps: options.update(m) if value in options: options[value]() elif None in options: options[None]()` `

` `def sample(x): switch(x, { _: lambda: print("other") for _ in 'cdef' }, { 'a': lambda: print("hello"), 'b': lambda: ( print("goodbye,"), print("!")), None: lambda: print("I dunno") })` `

` `class ChoiceManager: def __init__(self): self.__choice_table = \ { "CHOICE1" : self.my_func1, "CHOICE2" : self.my_func2, } def my_func1(self, data): pass def my_func2(self, data): pass def process(self, case, data): return self.__choice_table[case](data) ChoiceManager().process("CHOICE1", my_data)` `

` `class PacketManager: def __init__(self): self.__choice_table = \ { ControlMessage : self.my_func1, DiagnosticMessage : self.my_func2, } def my_func1(self, data): # process the control message here pass def my_func2(self, data): # process the diagnostic message here pass def process(self, pkt): return self.__choice_table[pkt.__class__](pkt) pkt = GetMyPacketFromNet() PacketManager().process(pkt) # isolated test or isolated usage example def test_control_packet(): p = ControlMessage() PacketManager().my_func1(p)` `

` `exec { 1: """ print ('one') """, 2: """ print ('two') """, 3: """ print ('three') """, }.get(value, """ print ('None') """)` `

Where `value` is the value. In C, this would be:

` `switch (value) { case 1: printf("one"); break; case 2: printf("two"); break; case 3: printf("three"); break; default: printf("None"); break; }` `

We can also create a helper function to do this:

` `def switch(value, cases, default): exec cases.get(value, default)` `

So we can use it like this for the example with one, two and three:

` `switch(value, { 1: """ print ('one') """, 2: """ print ('two') """, 3: """ print ('three') """, }, """ print ('None') """)` `

Expanding on Greg Hewgill's answer – We can encapsulate the dictionary-solution using a decorator:

` `def case(callable): """switch-case decorator""" class case_class(object): def __init__(self, *args, **kwargs): self.args = args self.kwargs = kwargs def do_call(self): return callable(*self.args, **self.kwargs) return case_class def switch(key, cases, default=None): """switch-statement""" ret = None try: ret = case[key].do_call() except KeyError: if default: ret = default.do_call() finally: return ret` `

This can then be used with the `@case` -decorator

` `@case def case_1(arg1): print 'case_1: ', arg1 @case def case_2(arg1, arg2): print 'case_2' return arg1, arg2 @case def default_case(arg1, arg2, arg3): print 'default_case: ', arg1, arg2, arg3 ret = switch(somearg, { 1: case_1('somestring'), 2: case_2(13, 42) }, default_case(123, 'astring', 3.14)) print ret` `

The good news are that this has already been done in NeoPySwitch -module. Simply install using pip:

` `pip install NeoPySwitch` `

I would just use if/elif/else statements. I think that it's good enough to replace the switch statement.

Just mapping some a key to some code is not really and issue as most people have shown using the dict. The real trick is trying to emulate the whole drop through and break thing. I don't think I've ever written a case statement where I used that "feature". Here's a go at drop through.

` `def case(list): reduce(lambda b, f: (b | f[0], {False:(lambda:None),True:f[1]}[b | f[0]]())[0], list, False) case([ (False, lambda:print(5)), (True, lambda:print(4)) ])` `

I was really imagining it as a single statement. I hope you'll pardon the silly formatting.

` `reduce( initializer=False, function=(lambda b, f: ( b | f[0] , { False: (lambda:None) , True : f[1] }[b | f[0]]() )[0] ), iterable=[ (False, lambda:print(5)), (True, lambda:print(4)) ] )` `

I hope that's valid python. It should give you drop through. of course the boolean checks could be expressions and if you wanted them to be evaluated lazily you could wrap them all in a lambda. I wouldn't be to hard to make it accept after executing some of the items in the list either. Just make the tuple (bool, bool, function) where the second bool indicates whether or not to break or drop through.

For the sake of completeness, here are some of my attempts back in stone-age:

I especially enjoy the use of "3. Select values with 'range comparisons'"

If you are really just returning a predetermined, fixed value, you could create a dictionary with all possible input indexes as the keys, along with their corresponding values. Also, you might not really want a function to do this – unless you're computing the return value somehow.

Oh, and if you feel like doing something switch-like, see here .

I was quite confused after reading the answer, but this cleared it all up:

` `def numbers_to_strings(argument): switcher = { 0: "zero", 1: "one", 2: "two", } return switcher.get(argument, "nothing")` `

This code is analogous to:

` `function(argument){ switch(argument) { case 0: return "zero"; case 1: return "one"; case 2: return "two"; default: return "nothing"; } }` `

Check the Source for more about dictionary mapping to functions.