Re: Don't want to do the regexp test twice

Discussion in 'Python' started by Bengt Richter, Jul 25, 2003.

  1. On Thu, 24 Jul 2003 23:44:57 +0200, Egbert Bouwman <> wrote:

    >While looping over a long list (with file records)
    >I use an (also long) if..elif sequence.
    >One of these elif's tests a regular expression, and
    >if the test succeeds, I want to use a part of the match.
    >Something like this:
    >
    >pat = re.compile(r'...')
    >for line in mylist:
    > if ... :
    > ....
    > elif ... :
    > ....
    > elif pat.search(line):
    > mat = pat.search(line)
    > elif ... :
    > ...
    > else ...:
    > ...
    >Is there a way to to do this job with only one pat.search(line) ?

    Hack #1 (list comprehension abuse):

    >>> import re
    >>> pat = re.compile(r'...')
    >>> mylist = ' a bc def ghij'.split(' ')
    >>> mylist

    ['', 'a', 'bc', 'def', 'ghij']
    >>> for line in mylist:

    ... if 1==2: 'naw'
    ... elif 3==4: 'neither'
    ... elif [1 for mat in [pat.search(line)] if mat]:
    ... print repr(mat), mat.groups(), mat.group()
    ... elif 4==5: 'haw'
    ... else:
    ... print 'final else'
    ...
    final else
    final else
    final else
    <_sre.SRE_Match object at 0x007F1260> () def
    <_sre.SRE_Match object at 0x007F5900> () ghi

    Hack #2: (attach temporary value to an instance of something
    that can accept attributes (almost any object):

    >>> import re
    >>> pat = re.compile(r'...')
    >>> mylist = ' a bc def ghij'.split(' ')
    >>> mylist

    ['', 'a', 'bc', 'def', 'ghij']
    >>> obj = type('Any',(),{})()
    >>> for line in mylist:

    ... if 1==2: 'naw'
    ... elif 3==4: 'neither'
    ... elif setattr(obj,'mat', pat.search(line)) or obj.mat:
    ... print repr(obj.mat), obj.mat.groups(), obj.mat.group()
    ... elif 4==5: 'haw'
    ... else:
    ... print 'final else'
    ...
    final else
    final else
    final else
    <_sre.SRE_Match object at 0x007F69C0> () def
    <_sre.SRE_Match object at 0x007F6980> () ghi

    The trick above is that setattr(...) return None, so the expression always continues to the or part.
    >>> setattr(obj,'xxx',123)
    >>> repr(setattr(obj,'xxx',123))

    'None'

    You can spell

    ... elif setattr(obj,'mat', pat.search(line)) or obj.mat:
    ... print repr(obj.mat), obj.mat.groups(), obj.mat.group()

    a little slicker if you make a special object to hold a binding to
    the pat.search result, e.g., h is the Holder instance in the following,
    which remembers the last thing passed to it and immediately returns it,
    and also returns that last thing on being called without an arg:

    >>> mylist

    ['', 'a', 'bc', 'def', 'ghij']
    >>> h = Holder()
    >>> for line in mylist:

    ... if 1==2: 'naw'
    ... elif 3==4: 'neither'
    ... elif h(pat.search(line)):
    ... print repr(h()), h().groups(), h().group()
    ... elif 4==5: 'haw'
    ... else:
    ... print 'final else'
    ...
    final else
    final else
    final else
    <_sre.SRE_Match object at 0x007F6FC0> () def
    <_sre.SRE_Match object at 0x007F6F80> () ghi

    Obviously
    ... print repr(h()), h().groups(), h().group()
    could have been
    ... mat=h(); print repr(mat), mat.groups(), mat.group()
    instead.

    E.g., using the leftover value in h:

    >>> print repr(h()), h().groups(), h().group()

    <_sre.SRE_Match object at 0x007F6F80> () ghi
    >>> mat=h(); print repr(mat), mat.groups(), mat.group()

    <_sre.SRE_Match object at 0x007F6F80> () ghi


    >Of course I can do this:
    >
    >for line in mylist:
    > mat = pat.search(line)
    > if ...:
    > ....
    > elif ...:
    > ....
    > elif mat:
    > ...
    >but the test is relevant in only a relatively small number of cases.
    >And i would like to know if there exists a general solution
    >for this kind of problem.


    Take a pick, but not the list comprehension ;-)

    Regards,
    Bengt Richter
     
    Bengt Richter, Jul 25, 2003
    #1
    1. Advertising

  2. On 25 Jul 2003 02:17:24 GMT, (Bengt Richter) wrote:
    [...]
    >You can spell
    >
    > ... elif setattr(obj,'mat', pat.search(line)) or obj.mat:
    > ... print repr(obj.mat), obj.mat.groups(), obj.mat.group()
    >
    >a little slicker if you make a special object to hold a binding to
    >the pat.search result, e.g., h is the Holder instance in the following,
    >which remembers the last thing passed to it and immediately returns it,
    >and also returns that last thing on being called without an arg:
    >
    > >>> mylist

    > ['', 'a', 'bc', 'def', 'ghij']
    > >>> h = Holder()
    > >>> for line in mylist:

    > ... if 1==2: 'naw'
    > ... elif 3==4: 'neither'
    > ... elif h(pat.search(line)):
    > ... print repr(h()), h().groups(), h().group()
    > ... elif 4==5: 'haw'
    > ... else:
    > ... print 'final else'
    > ...
    > final else
    > final else
    > final else
    > <_sre.SRE_Match object at 0x007F6FC0> () def
    > <_sre.SRE_Match object at 0x007F6F80> () ghi
    >
    >Obviously
    > ... print repr(h()), h().groups(), h().group()
    >could have been
    > ... mat=h(); print repr(mat), mat.groups(), mat.group()
    >instead.
    >

    Sorry, I seem to have snipped out a Holder definition, in case anyone cares:

    >>> class Holder(object):

    ... def __call__(self, *args):
    ... if args: self.val = args[0]
    ... return self.val
    ...
    >>> h = Holder()
    >>> h(123)

    123
    >>> h()

    123
    >>> h(345),h(),h(678),h() # result depends on left-to-right eval here

    (345, 345, 678, 678)

    Regards,
    Bengt Richter
     
    Bengt Richter, Jul 25, 2003
    #2
    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. Kiuhnm

    twice(twice(x))

    Kiuhnm, Apr 1, 2006, in forum: C++
    Replies:
    2
    Views:
    395
    Kiuhnm
    Apr 1, 2006
  2. Skybuck Flying

    Call oddities: &Test() vs &Test vs Test

    Skybuck Flying, Oct 4, 2009, in forum: C Programming
    Replies:
    1
    Views:
    704
    Skybuck Flying
    Oct 4, 2009
  3. Raphael Bauduin
    Replies:
    6
    Views:
    99
    Nathaniel Talbott
    Feb 2, 2005
  4. Joao Silva
    Replies:
    16
    Views:
    363
    7stud --
    Aug 21, 2009
  5. Matìj Cepl

    new RegExp().test() or just RegExp().test()

    Matìj Cepl, Nov 24, 2009, in forum: Javascript
    Replies:
    3
    Views:
    181
    Matěj Cepl
    Nov 24, 2009
Loading...

Share This Page