Avoiding if..elsif statements

Discussion in 'Python' started by unexpected, Aug 25, 2006.

  1. unexpected

    unexpected Guest

    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?
    unexpected, Aug 25, 2006
    #1
    1. Advertising

  2. "unexpected" <> wrote:

    > 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>
    Fredrik Lundh, Aug 25, 2006
    #2
    1. Advertising

  3. > 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']()
    Daniel Nogradi, Aug 25, 2006
    #3
  4. unexpected

    Simon Forman Guest

    unexpected wrote:
    > 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)()
    Simon Forman, Aug 25, 2006
    #4
  5. unexpected

    Chaz Ginger Guest

    unexpected wrote:
    > 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
    Chaz Ginger, Aug 26, 2006
    #5
  6. unexpected

    unexpected Guest

    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 Lundh wrote:
    > "unexpected" <> wrote:
    >
    > > 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>
    unexpected, Aug 26, 2006
    #6
  7. "unexpected" <> wrote:

    > 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>
    Fredrik Lundh, Aug 26, 2006
    #7
  8. unexpected

    Carl Banks Guest

    unexpected wrote:
    > 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
    Carl Banks, Aug 26, 2006
    #8
  9. Try it and see. Functions are first-class citizens in Python.

    On Aug 25, 2006, at 6:36 PM, unexpected wrote:

    > 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?
    >
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    Ghalib Suleiman, Aug 26, 2006
    #9
  10. unexpected

    Tal Einat Guest

    Fredrik Lundh wrote:
    > "unexpected" <> wrote:
    >
    > > 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]
    Tal Einat, Aug 27, 2006
    #10
  11. Tal Einat wrote:

    > 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>
    Fredrik Lundh, Aug 27, 2006
    #11
  12. unexpected

    Tal Einat Guest

    Fredrik Lundh wrote:
    > Tal Einat wrote:
    >
    > > 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>


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

    - Tal
    Tal Einat, Aug 27, 2006
    #12
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. michaelb
    Replies:
    0
    Views:
    453
    michaelb
    Sep 30, 2006
  2. karlwijk

    if/elsif problem

    karlwijk, Apr 16, 2007, in forum: VHDL
    Replies:
    3
    Views:
    648
    quantum_dot
    Apr 18, 2007
  3. palo
    Replies:
    0
    Views:
    1,277
  4. Brad Smallridge

    one hot machine without elsif

    Brad Smallridge, Feb 16, 2009, in forum: VHDL
    Replies:
    10
    Views:
    770
  5. ccc31807

    formatting a number of elsif statements

    ccc31807, Jul 5, 2009, in forum: Perl Misc
    Replies:
    13
    Views:
    132
Loading...

Share This Page