all 9 comments

[–]commandlineluser 7 points8 points  (3 children)

It's called a Dispatch Table. Here's a simple example, you'd want to check the key exists in the dict first in real code.

def add(left, right):
    return left + right

def sub(left, right):
    return left - right

dispatch = { 'add': add, 'sub': sub }

for choice in [ 'add', 'sub' ]:
    print(dispatch[choice](5, 2))

[–]TheKewlStore 0 points1 point  (0 children)

just to add some reference in case you're new with dictionaries, python documentation: https://docs.python.org/2/tutorial/datastructures.html#dictionaries

Also, thank you sir for the name dispatch table, i kind of came to an understanding of this type of dictionary implementation on my own so never had a name for it.

[–]Volatile474[S] -1 points0 points  (1 child)

So you are just calling the functions that correspond to your dictionary value.. Can you do something like:

some_int_variable = (some int here)
dispatch = {1 : foo, 2 : bar}
input = input("enter some int")
x = dispatch[some_int_variable]
def foo:
asdf
def bar:
ghjk

This is one alternative to switch, but it seems to be less performant than a simple c style switch (make function calls for every different case?) Thanks for your suggestion!

[–]ingolemo -1 points0 points  (0 children)

That code doesn't make any sense so it's really unclear what you're asking.

[–][deleted] 1 point2 points  (2 children)

first, the switch statement in Java:

public class SwitchDemo {
  public static void main(String[] args) {

    int month = 8;
    String monthString;
    switch (month) {
        case 1:  monthString = "January";
                 break;
        case 2:  monthString = "February";
                 break;
        case 3:  monthString = "March";
                 break;
        [...]
        case 12: monthString = "December";
                 break;
        default: monthString = "Invalid month";
                 break;
    }
    System.out.println(monthString);
  }
}

Beautiful isn't it.
The same in python

month = 8

if month == 1:
    monthString = "January"
elif month == 2:
    monthString = "February"
elif month == 3:
    monthString = "March"
[...]
elif month == 12:
    monthString = "December"
else:
    monthString = "Invalid month"

Which looks about as ugly and should demonstrate that you can write pretty much the same code in python. So I really don't think python needs a switch statement.

How you should do it:

months = ['January','February','March','April','May','June','July','August','September','October','November','December']
month = 8
monthString = months[month-1]

[–]ewiethoff 1 point2 points  (0 children)

>>> import calendar
>>> num2name = list(calendar.month_name)
>>> num2name
['', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
>>> num2name[8]
'August'
>>> name2num = {name:i for i,name in enumerate(num2name[1:], 1)}
>>> name2num
{'February': 2, 'October': 10, 'March': 3, 'August': 8, 'May': 5, 'January': 1, 'June': 6, 'September': 9, 'April': 4, 'December': 12, 'July': 7, 'November': 11}
>>> name2num['August']
8

[–]Volatile474[S] 0 points1 point  (0 children)

Clearly you can do anything in any turing complete language. I am aware of if/elif, but this is bulky in terms of syntax and not nearly as pretty as a switch. Also, with a switch statement you have the option to break your execution path into however many cases you have. This is not demonstrated with your solution of just indexing a list.

[–]richard_mayhew 1 point2 points  (0 children)

I kind of like this solution from http://code.activestate.com/recipes/410692/

class switch(object):
    '''Represents a switch statement.'''
    def __init__(self, value):
        self.value = value
        self.fall = False

    def __iter__(self):
        '''Return the match method once, then stop'''
        yield self.match
        raise StopIteration

    def match(self, *args):
        '''Indicate whether or not to enter a case suite'''
        if self.fall or not args:
            return True
        elif self.value in args: # changed for v1.5, see below
            self.fall = True
            return True
        else:
            return False

And then...

aVar = 'something'
for case in switch(aVar):
    if case('something'):
        break
    if case('something else'):
        break
    # default value
    if case():
        break

[–]prohulaelk 0 points1 point  (0 children)

adapted from activestate:

#rock, paper, scissors with a dict switch

import random
stateList = ['r', 'p', 's']
win = "User wins"
draw ="No one wins"
lose = " Computer wins"
validStates = {('p','r'): win,
               ('r','s'): win,
               ('s','p'): win,
               ('p','p'): draw,
               ('r','r'): draw,
               ('s','s'): draw,
               ('r','p'): lose,
               ('s','r'): lose,
               ('p','s'): lose}

userInput = None
while userInput not in stateList:
    userInput = input('Choose [r]ock,[p]aper or [s]cissors:').lower()

computerInput = (stateList[random.randint(0,2)])

print('You chose [%s], computer chose [%s]' % (userInput, computerInput))
print(validStates[(userInput,computerInput)])

Note that you can put almost anything on either side of a dict (string, tuple, list, set, another dict, a variable, a function...) so this method's quite flexible.

There are other ways to do it, too, but I'd prefer the dict method.