Avoiding if..elsif statements

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • unexpected

    #1

    Avoiding if..elsif statements

    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" :
    somethingElseCl ass.func()
    elsif value == "anotherthi ng":
    anotherthingCla ss.func()
    elsif value == "yetanotherthin g":
    yetanotherthing Class.func()

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

  • Fredrik Lundh

    #2
    Re: Avoiding if..elsif statements

    "unexpected " <sumesh.chopra@ gmail.comwrote:
    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" :
    somethingElseCl ass.func()
    elsif value == "anotherthi ng":
    anotherthingCla ss.func()
    elsif value == "yetanotherthin g":
    yetanotherthing Class.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" : somethingElseCl ass.func,
    "anotherthi ng": anotherthingCla ss.func,
    "yetanotherthin g": yetanotherthing Class.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>



    Comment

    • Daniel Nogradi

      #3
      Re: Avoiding if..elsif statements

      Code:
      >
      value = self.dictionary .get(keyword)[0]
      >
      if value == "something" :
      somethingClass. func()
      elsif value == "somethingElse" :
      somethingElseCl ass.func()
      elsif value == "anotherthi ng":
      anotherthingCla ss.func()
      elsif value == "yetanotherthin g":
      yetanotherthing Class.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']()

      Comment

      • Simon Forman

        #4
        Re: Avoiding if..elsif statements

        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" :
        somethingElseCl ass.func()
        elsif value == "anotherthi ng":
        anotherthingCla ss.func()
        elsif value == "yetanotherthin g":
        yetanotherthing Class.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 = somethingElseCl ass.func,
        anotherthing = anotherthingCla ss.func,
        yetanotherthing = yetanotherthing Class.func
        )

        def default():
        pass


        # call it like this

        dispatch.get(sw itch_value, default)()

        Comment

        • Chaz Ginger

          #5
          Re: Avoiding if..elsif statements

          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" :
          somethingElseCl ass.func()
          elsif value == "anotherthi ng":
          anotherthingCla ss.func()
          elsif value == "yetanotherthin g":
          yetanotherthing Class.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':so methingClass.fu nc,'somethingel se':somethingel seClass.func)

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



          Comment

          • unexpected

            #6
            Re: Avoiding if..elsif statements

            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 " <sumesh.chopra@ gmail.comwrote:
            >
            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" :
            somethingElseCl ass.func()
            elsif value == "anotherthi ng":
            anotherthingCla ss.func()
            elsif value == "yetanotherthin g":
            yetanotherthing Class.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" : somethingElseCl ass.func,
            "anotherthi ng": anotherthingCla ss.func,
            "yetanotherthin g": yetanotherthing Class.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>

            Comment

            • Fredrik Lundh

              #7
              Re: Avoiding if..elsif statements

              "unexpected " <sumesh.chopra@ gmail.comwrote:
              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(argu ment 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>



              Comment

              • Carl Banks

                #8
                Re: Avoiding if..elsif statements

                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

                Comment

                • Ghalib Suleiman

                  #9
                  Re: Avoiding if..elsif statements

                  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" :
                  somethingElseCl ass.func()
                  elsif value == "anotherthi ng":
                  anotherthingCla ss.func()
                  elsif value == "yetanotherthin g":
                  yetanotherthing Class.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

                  Comment

                  • Tal Einat

                    #10
                    Re: Avoiding if..elsif statements


                    Fredrik Lundh wrote:
                    "unexpected " <sumesh.chopra@ gmail.comwrote:
                    >
                    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(somethi ngClass.func),
                    "somethingElse" : Command(somethi ngElseClass.fun c, "moo",
                    [1,2,3]),
                    "anotherthi ng": Command(another thingClass.func , 'a', 'b', 'c'),
                    "yetanotherthin g": Command(yetanot herthingClass.f unc,
                    verbose=True),
                    }

                    dispatch[value]()

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

                    Comment

                    • Fredrik Lundh

                      #11
                      Re: Avoiding if..elsif statements

                      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>

                      Comment

                      • Tal Einat

                        #12
                        Re: Avoiding if..elsif statements


                        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

                        Comment

                        Working...