Avoiding if..elsif statements

U

unexpected

I have a program where based on a specific value from a dictionary, I
call a different function. Currently, I've implemented a bunch of
if..elsif statements to do this, but it's gotten to be over 30 right
now and has gotten rather tedious. Is there a more efficient way to do
this?

Code:

value = self.dictionary.get(keyword)[0]

if value == "something":
somethingClass.func()
elsif value == "somethingElse":
somethingElseClass.func()
elsif value == "anotherthing":
anotherthingClass.func()
elsif value == "yetanotherthing":
yetanotherthingClass.func()

Is it possible to store these function calls in a dictionary so that I
could just call the dictionary value?
 
F

Fredrik Lundh

unexpected said:
I have a program where based on a specific value from a dictionary, I
call a different function. Currently, I've implemented a bunch of
if..elsif statements to do this, but it's gotten to be over 30 right
now and has gotten rather tedious. Is there a more efficient way to do
this?

Code:

value = self.dictionary.get(keyword)[0]

if value == "something":
somethingClass.func()
elsif value == "somethingElse":
somethingElseClass.func()
elsif value == "anotherthing":
anotherthingClass.func()
elsif value == "yetanotherthing":
yetanotherthingClass.func()

Is it possible to store these function calls in a dictionary so that I
could just call the dictionary value?

but of course (did you try it?). here's an outline:

dispatch = {
"something": somethingClass.func, # note: no () here
"somethingElse": somethingElseClass.func,
"anotherthing": anotherthingClass.func,
"yetanotherthing": yetanotherthingClass.func,
}

...

dispatch[value]() # note: do the call here!

or, a bit more robust:

try:
func = dispatch[value]
except KeyError:
print "- no handler for", value
else:
func()

tweak as necessary.

</F>
 
D

Daniel Nogradi

Code:
value = self.dictionary.get(keyword)[0]

if value == "something":
somethingClass.func()
elsif value == "somethingElse":
somethingElseClass.func()
elsif value == "anotherthing":
anotherthingClass.func()
elsif value == "yetanotherthing":
yetanotherthingClass.func()

Is it possible to store these function calls in a dictionary so that I
could just call the dictionary value?

How about (untested):

def x():
print 'x'

def y():
print 'y'

funcdict={ 'valuex': x, 'valuey': y }

funcdict['valuex']()
 
S

Simon Forman

unexpected said:
I have a program where based on a specific value from a dictionary, I
call a different function. Currently, I've implemented a bunch of
if..elsif statements to do this, but it's gotten to be over 30 right
now and has gotten rather tedious. Is there a more efficient way to do
this?

Code:

value = self.dictionary.get(keyword)[0]

if value == "something":
somethingClass.func()
elsif value == "somethingElse":
somethingElseClass.func()
elsif value == "anotherthing":
anotherthingClass.func()
elsif value == "yetanotherthing":
yetanotherthingClass.func()

Is it possible to store these function calls in a dictionary so that I
could just call the dictionary value?

Yup.

dispatch = dict(
something = somethingClass.func,
somethingElse = somethingElseClass.func,
anotherthing = anotherthingClass.func,
yetanotherthing = yetanotherthingClass.func
)

def default():
pass


# call it like this

dispatch.get(switch_value, default)()
 
C

Chaz Ginger

unexpected said:
I have a program where based on a specific value from a dictionary, I
call a different function. Currently, I've implemented a bunch of
if..elsif statements to do this, but it's gotten to be over 30 right
now and has gotten rather tedious. Is there a more efficient way to do
this?

Code:

value = self.dictionary.get(keyword)[0]

if value == "something":
somethingClass.func()
elsif value == "somethingElse":
somethingElseClass.func()
elsif value == "anotherthing":
anotherthingClass.func()
elsif value == "yetanotherthing":
yetanotherthingClass.func()

Is it possible to store these function calls in a dictionary so that I
could just call the dictionary value?
Why not do it this way?

foo =
{'something':somethingClass.func,'somethingelse':somethingelseClass.func)

if foo.has_key(value) :
foo[value]()
else :
raise OMG, "%s isn't known" % value
 
U

unexpected

the missing () was the trick!

However, I'm passing in a few variables, so I can't just take it
out-though every single function would be passing the same variables.

so something.func() is actually
something.func(string, list)

How would I modify it to include them? Sorry I didn't include them the
first time, I was trying to simplify it to make it easier...oops!

Fredrik said:
unexpected said:
I have a program where based on a specific value from a dictionary, I
call a different function. Currently, I've implemented a bunch of
if..elsif statements to do this, but it's gotten to be over 30 right
now and has gotten rather tedious. Is there a more efficient way to do
this?

Code:

value = self.dictionary.get(keyword)[0]

if value == "something":
somethingClass.func()
elsif value == "somethingElse":
somethingElseClass.func()
elsif value == "anotherthing":
anotherthingClass.func()
elsif value == "yetanotherthing":
yetanotherthingClass.func()

Is it possible to store these function calls in a dictionary so that I
could just call the dictionary value?

but of course (did you try it?). here's an outline:

dispatch = {
"something": somethingClass.func, # note: no () here
"somethingElse": somethingElseClass.func,
"anotherthing": anotherthingClass.func,
"yetanotherthing": yetanotherthingClass.func,
}

...

dispatch[value]() # note: do the call here!

or, a bit more robust:

try:
func = dispatch[value]
except KeyError:
print "- no handler for", value
else:
func()

tweak as necessary.

</F>
 
F

Fredrik Lundh

unexpected said:
However, I'm passing in a few variables, so I can't just take it
out-though every single function would be passing the same variables.

so something.func() is actually
something.func(string, list)

How would I modify it to include them?

just add the parameters to the call:

dispatch[value](string, list) # note: do the call here!

in Python, an explicit call is always written as

expression(argument list)

where expression yields a callable object. in your original case,
the expression was a bound method; in the modified example,
the expression is a dictionary lookup. the actual call part looks
the same way, in both cases.

</F>
 
C

Carl Banks

unexpected said:
Currently, I've implemented a bunch of
if..elsif statements to do this, but it's gotten to be over 30 right
now and has gotten rather tedious. Is there a more efficient way to do
this?

Use something other than Perl.

:)


Carl Banks
 
T

Tal Einat

Fredrik said:
unexpected said:
However, I'm passing in a few variables, so I can't just take it
out-though every single function would be passing the same variables.

so something.func() is actually
something.func(string, list)

How would I modify it to include them?

just add the parameters to the call:

dispatch[value](string, list) # note: do the call here!

This will work great if all of your functions recieve the same
argument(s). If not, there are still simple solutions.

I would suggest a solution like this, since it's simple and generic:

class Command (object):
def __init__(self, func, *args, **kw):
self.func = func
self.args = args
self.kw = kw
def __call__(self, *args, **kw):
args = self.args+args
kw.update(self.kw)
apply(self.func, args, kw)

An instance of the Command class can be called just like a function,
and it will call the orginial function with the arguments it was
instantiated with. (You can also pass additional arguments at the call
itself)

dispatch = {
"something": Command(somethingClass.func),
"somethingElse": Command(somethingElseClass.func, "moo",
[1,2,3]),
"anotherthing": Command(anotherthingClass.func, 'a', 'b', 'c'),
"yetanotherthing": Command(yetanotherthingClass.func,
verbose=True),
}

dispatch[value]()

- Tal Einat
reduce(lambda m,x:[m+s[-1] for i,s in enumerate(sorted(m))],
[[chr(154-ord(c)) for c in '.&-&,l.Z95193+179-']]*18)[3]
 
F

Fredrik Lundh

Tal said:
This will work great if all of your functions recieve the same
argument(s).

I assumed "every single function would be passing the same variables"
meant exactly that, of course.

</F>
 
T

Tal Einat

Fredrik said:
I assumed "every single function would be passing the same variables"
meant exactly that, of course.

</F>

Right, as usual. I sort of missed that... ;)

- Tal
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top