assignment expression peeve

Bengt Richter bokr at oz.net
Thu Oct 16 09:16:53 EDT 2003


On 14 Oct 2003 21:12:29 -0700, Paul Rubin <http://phr.cx@NOSPAM.invalid> wrote:

>OK, I want to scan a file for lines matching a certain regexp.  I'd
>like to use an assignment expression, like
>
>   for line in file:
>      if (g := re.match(pat, line)):
>         croggle(g.group(1))
>
>Since there are no assignment expressions in Python, I have to use a
>temp var.  That's a little more messy, but bearable:
>
>   for line in file:
>      g = re.match(pat, line)
>      if g:
>         croggle(g.group(1))
>
>It gets annoying when there are 4 different regexps that the line
>might match, and I want to do something different depending on which
>one matches.  That's not that uncommon a text scanning situation.
>With assignment expressions, it's a very natural if/elif chain:
>
>   for line in file:
>     if g := re.match(pat1, line):
>        croggle(g.group(1), 17)
>     elif g := re.match(pat2, line):
>        x = mugwump(g.group(3))
>        y = wumpus(g.group(2))
>        return defenestrate(x, y+3)
>     elif g := re.match(pat3, line):
>        # do something completely different with groups of g
>     elif g := re.match(pat4, line):
>        # more of the same
>
I posted a "holder" class a fairly long time ago that I'd use (untested code here):

    class Holder(object):
        def __call__(self, *v)	# v is () or (the_value,)
            if v: self.v = v[0]
            return self.v

    value =  Holder() # as many as you need simultaneous recall of distinct expressions

    for line in file:
      if value( re.match(pat1, line) ):
         croggle(value().group(1), 17)     # or you could use a short name: len('h()') == len('h.v') ;-)
      elif value( re.match(pat2, line) ):
         x = mugwump(value().group(3))
         y = wumpus(value().group(2))
         return defenestrate(x, y+3)
      elif value( re.match(pat3, line) ):
         # do something completely different with groups of g
      elif value( re.match(pat4, line) ):
         # more of the same


>Without assigment expressions, it gets unspeakably ugly.  You have to
>use a deeply nested if/else if sequence where you match the regexp and
>test the result on 2 separate lines at each branch, or reorganize the
>code to use some kind of dispatch table (good if there's a lot more
>than 4 regexps, but overkill for just 4), or whatever.  I ended up
>creating a special class instance just to match a regexp and remember
>the result, so I could write in the if/elif style.
>
>This kind of regexp matching is a common pattern and I keep wanting
>assignment expressions whenever I code it, and end up crocking up some
>silly workaround.

Is the above what you did? You only need to do it once (although its
often easier to rwrite things like this than find where they're filed ;-)

Regards,
Bengt Richter




More information about the Python-list mailing list