473,224 Members | 1,550 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,224 software developers and data experts.

Using a switch-like if/else construct versus a dictionary?

Which is better: using an if/else construct to simulate a C switch or
use a dictionary? Example:

def foo():
if c == 1:
doCase1()
elif c == 2:
doCase2()
elif c == 3:
doCase3()
elif c == 4:
doCase4()
elif c == 5:
doCase5()
else:
raise "shouldn't get here"
or:

def foo():
def doCase1():
pass
def doCase2():
pass
def doCase3():
pass
def doCase4():
pass
def doCase5():
pass

handle_case = {}
handle_case[1] = doCase1()
handle_case[2] = doCase2()
handle_case[3] = doCase3()
handle_case[4] = doCase4()
handle_case[5] = doCase5()
handle_case[c]()

Note that in this situation using OO polymorphism instead of a switch-
like construct wouldn't be applicable, or at least I can't see how it
could be.

Thanks in advance for any tips!

-- Arcadio

Jun 19 '07 #1
6 1682

asincero ha escrit:
def foo():
def doCase1():
pass
def doCase2():
pass
def doCase3():
pass
def doCase4():
pass
def doCase5():
pass

handle_case = {}
handle_case[1] = doCase1()
handle_case[2] = doCase2()
handle_case[3] = doCase3()
handle_case[4] = doCase4()
handle_case[5] = doCase5()
Sorry, but I think this is not correct. Now, you put the result of the
function call into the dictionary, but you want the function address.

The correct code is:
handle_case = {}
handle_case[1] = doCase1
handle_case[2] = doCase2
handle_case[3] = doCase3
handle_case[4] = doCase4
handle_case[5] = doCase5

Or:
handle_case = { 1: doCase1, 2: doCase2, 3: doCase3, 4: doCase4, 5:
doCase 5 }

Or:
try:
{ 1: doCase1, 2: doCase2, 3: doCase3, 4: doCase4, 5: doCase 5 }
[c]()
except:
print "Catch the correct exception"

But this solutions only works fine if the params of the functions are
the same for all calls (in if/else construct you don't need it).

Bye!

--
Helio Tejedor

Jun 19 '07 #2
asincero <as******@gmail.comwrote:
Which is better: using an if/else construct to simulate a C switch or
use a dictionary? Example:
Here is a technique I've used a lot. I think I learnt it from "Dive
into Python"

class foo(object):
def do_1(self):
print "I'm 1"
def do_2(self):
print "I'm 2"
def do_3(self):
print "I'm 3"
def do_4(self):
print "I'm 4"
def do_5(self):
print "I'm 5"
def dispatch(self, x):
getattr(self, "do_"+str(x))()

f = foo()
f.dispatch(1)
f.dispatch(3)
f.dispatch(17)

It will blow up gracelessly with an AttributeError if you pass it
something which it can't handle. That is easy to fix.

You could name dispatch, __call__ if you wanted a slightly neater
syntax.

f = foo()
f(1)
f(3)
f(17)

You can do the same thing in a function using locals()["do_"+str(x)]
but I always find that if I've got to that point I should be using a
class instead.
Note that in this situation using OO polymorphism instead of a switch-
like construct wouldn't be applicable, or at least I can't see how it
could be.
If there is a "type" or "id" in your objects and you are switching on
it, then you should be using polymorphism. Make each seperate "type"
a seperate class type and implement the methods for each one. All the
switches will disappear from your code like magic!

Post more details if you want more help!

--
Nick Craig-Wood <ni**@craig-wood.com-- http://www.craig-wood.com/nick
Jun 19 '07 #3
asincero <as******@gmail.comwrites:
def foo():
def doCase1():
pass
def doCase2():
pass
def doCase3():
pass
def doCase4():
pass
def doCase5():
pass

handle_case = {}
handle_case[1] = doCase1()
handle_case[2] = doCase2()
handle_case[3] = doCase3()
handle_case[4] = doCase4()
handle_case[5] = doCase5()
handle_case[c]()
(The above code is wrong. You want the dictionary to map to functions,
not to the result of calling those functions; the call to the function
comes later.)

Why not construct the dictionary in one step? ::

handle_case = {
1: do_case_1,
2: do_case_2,
3: do_case_3,
4: do_case_4,
5: do_case_5,
}
handle_case[c]()

You could even perform the lookup and function call in the same
statement as creating the dictionary, but I prefer the above form for
its readability.
Note that in this situation using OO polymorphism instead of a switch-
like construct wouldn't be applicable, or at least I can't see how it
could be.
I'm not sure what you mean. What would you apply polymorphism to, and
what would be the desired result?

--
\ "I used to work in a fire hydrant factory. You couldn't park |
`\ anywhere near the place." -- Steven Wright |
_o__) |
Ben Finney
Jun 20 '07 #4
asincero <as******@gmail.comwrote:
handle_case = {}
handle_case[1] = doCase1()
handle_case[2] = doCase2()
handle_case[3] = doCase3()
handle_case[4] = doCase4()
handle_case[5] = doCase5()
handle_case[c]()
If the switch values are simple integers then a list would be a more
obvious choice:

handle_case = [ doCase1, doCase2, doCase3, doCase4, doCase5 ]
handle_case[c-1]()
Note that in this situation using OO polymorphism instead of a switch-
like construct wouldn't be applicable, or at least I can't see how it
could be.
That is often the case when you reduce your question to a mickeymouse do
nothing example.

There are many ways to write code that could be written using a switch
statement. If you took a few real use-cases then you would probably each
one needs a different technique for best effect depending on the number
of different cases, the values which must be accessed within each case,
the side-effects (if any) expected from handling the case etc.

The obvious options include: if/elif chain; a list or dictionary
containing data values (not functions); a list or dict containing
functions; command pattern (i.e. a class with a dispatch method); a
class hierarchy and polymorphism; visitor pattern.

For an example of the last of these see
http://www.chris-lamb.co.uk/blog/200...ern-in-python/
which uses decorators to produce a very clean implementation using (I
think) PyProtocols dispatch.
Jun 20 '07 #5
Ahh .. yes of course, you are right. I mis-typed. I like how you
defined the dictionary all in one statement, though. I didn't think
of doing it that way.

-- Arcadio
On Jun 19, 4:11 pm, heltena <helt...@gmail.comwrote:
asincero ha escrit:
def foo():
def doCase1():
pass
def doCase2():
pass
def doCase3():
pass
def doCase4():
pass
def doCase5():
pass
handle_case = {}
handle_case[1] = doCase1()
handle_case[2] = doCase2()
handle_case[3] = doCase3()
handle_case[4] = doCase4()
handle_case[5] = doCase5()

Sorry, but I think this is not correct. Now, you put the result of the
function call into the dictionary, but you want the function address.

The correct code is:
handle_case = {}
handle_case[1] = doCase1
handle_case[2] = doCase2
handle_case[3] = doCase3
handle_case[4] = doCase4
handle_case[5] = doCase5

Or:
handle_case = { 1: doCase1, 2: doCase2, 3: doCase3, 4: doCase4, 5:
doCase 5 }

Or:
try:
{ 1: doCase1, 2: doCase2, 3: doCase3, 4: doCase4, 5: doCase 5 }
[c]()
except:
print "Catch the correct exception"

But this solutions only works fine if the params of the functions are
the same for all calls (in if/else construct you don't need it).

Bye!

--
Helio Tejedor

Jun 20 '07 #6
On Jun 19, 12:40 pm, asincero <asinc...@gmail.comwrote:
Which is better: using an if/else construct to simulate a C switch or
use a dictionary? Example:
Whichever results in the clearest code that meets the performance
requirements.

FWIW, if you define the dictionary beforehand, the dict solution is
O(1) while if/else is O(N), which can be important.

-Mike

Jun 25 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Robert Scheer | last post by:
Hi. I am trying to use switch this way, without success: //thedata is a numeric variable switch (thedata) { case < 10: ... case < 20: ...
2
by: Tom Morgan | last post by:
Hi everyone, I'm having a brain freeze today so if the answer is a misplacced comma or a missing command, I would be happy. What I want to do is use access to return results via an .asp page. ...
1
by: wayneh | last post by:
I have an option group on a form with three choices "Yes/No/All" I'm using a switch function in a query to filter records on a Yes/No field. There is no problem displaying records that are either...
27
by: Yuriy Solodkyy | last post by:
Hi VS 2005 beta 2 successfully compiles the following: using System; using System.Collections.Generic; using System.Text; namespace ConsoleApplication1 { class Program {
25
by: v4vijayakumar | last post by:
'continue' within switch actually associated with the outer 'while' loop. Is this behavior protable? int ch = '\n'; while (true) { switch(ch) { case '\n': cout << "test"; continue; } }
67
by: Rui Maciel | last post by:
I've been delving into finite state machines and at this time it seems that the best way to implement them is through an intense use of the goto statement. Yet, everyone plus their granmother is...
10
by: kkirtac | last post by:
Hi, i have a void pointer and i cast it to an appropriate known type before using. The types which i cast this void* to are, from the Intel's open source computer vision library. Here is my piece...
8
by: eeffoc | last post by:
I've got a set of six radio buttons inside of a list box and what I'm trying to accomplish is generate a random number all with different ranges (Dice for d&d) depending on what radio button is...
0
by: srinivas srinivas | last post by:
Hi, I am developing simple peer-peer RTC application for monitoring the SDP packets and i need to set the TLS security for the transport. But iam struggling to achieving this. Iam using IP...
11
by: =?Utf-8?B?anAybXNmdA==?= | last post by:
Can switch statements be nested? I've got a large routine that runs off of a switch statement. If one of the switches in switch #1 is true, that enters switch statement #2. Some of the...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: mar23 | last post by:
Here's the situation. I have a form called frmDiceInventory with subform called subfrmDice. The subform's control source is linked to a query called qryDiceInventory. I've been trying to pick up the...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.