affectation in if statement

P

Paul Rubin

samb said:
or like :

m = re.match(r'define\s+(\S+)\s*{$', line)
if m:
thing = m.group(1)
else:
m = re.match(r'include\s+(\S+)$', line)
if m:
thing = m.group(1)
else
thing = ""

Which isn't nice neither because I'm going to have maybe 20 match
tests and I wouldn't like to have 20 indentations.

for pat in [r'define\s+(\S+)\s*{$', r'include\s+(\S+)$', ...]:
m = re.match(pat, line)
...
 
S

samb

Hi,

I'm trying to do something like :

if m = re.match(r'define\s+(\S+)\s*{$', line):
thing = m.group(1)
elif m = re.match(r'include\s+(\S+)$', line):
thing = m.group(1)
else
thing = ""

But in fact I'm not allowed to affect a variable in "if" statement.
My code should then look like :

if re.match(r'define\s+(\S+)\s*{$', line):
m = re.match(r'define\s+(\S+)\s*{$', line)
thing = m.group(1)
elif re.match(r'include\s+(\S+)$', line):
m = re.match(r'include\s+(\S+)$', line)
thing = m.group(1)
else
thing = ""

Which is not nice because I'm doing twice the same instruction
or like :

m = re.match(r'define\s+(\S+)\s*{$', line)
if m:
thing = m.group(1)
else:
m = re.match(r'include\s+(\S+)$', line)
if m:
thing = m.group(1)
else
thing = ""

Which isn't nice neither because I'm going to have maybe 20 match
tests and I wouldn't like to have 20 indentations.

Anyone a recommendation?

Thanks!
 
C

Chris Rebert

Hi,

I'm trying to do something like :

if m = re.match(r'define\s+(\S+)\s*{$', line):
   thing = m.group(1)
elif m = re.match(r'include\s+(\S+)$', line):
   thing = m.group(1)
else
   thing = ""

But in fact I'm not allowed to affect a variable in "if" statement.
My code should then look like :

if re.match(r'define\s+(\S+)\s*{$', line):
   m = re.match(r'define\s+(\S+)\s*{$', line)
   thing = m.group(1)
elif re.match(r'include\s+(\S+)$', line):
   m = re.match(r'include\s+(\S+)$', line)
   thing = m.group(1)
else
   thing = ""

Which is not nice because I'm doing twice the same instruction
or like :

m = re.match(r'define\s+(\S+)\s*{$', line)
if m:
   thing = m.group(1)
else:
   m = re.match(r'include\s+(\S+)$', line)
   if m:
       thing = m.group(1)
   else
       thing = ""

Which isn't nice neither because I'm going to have maybe 20 match
tests and I wouldn't like to have 20 indentations.

Anyone a recommendation?

def extract_thing(line):
for regex in (r'define\s+(\S+)\s*{$', r'include\s+(\S+)$'):
m = re.match(regex, line)
if m: return m.group(1)
return ""

Or if the real code is more complicated than your example:

def extract_thing(line):
m = re.match(r'define\s+(\S+)\s*{$', line)
if m: return m.group(1)

m = re.match(r'include\s+(\S+)$', line)
if m: return m.group(1)

#etc...

return ""

Cheers,
Chris
 
G

Gary Herron

samb said:
Hi,

I'm trying to do something like :

if m = re.match(r'define\s+(\S+)\s*{$', line):
thing = m.group(1)
elif m = re.match(r'include\s+(\S+)$', line):
thing = m.group(1)
else
thing = ""

But in fact I'm not allowed to affect a variable in "if" statement.
My code should then look like :

if re.match(r'define\s+(\S+)\s*{$', line):
m = re.match(r'define\s+(\S+)\s*{$', line)
thing = m.group(1)
elif re.match(r'include\s+(\S+)$', line):
m = re.match(r'include\s+(\S+)$', line)
thing = m.group(1)
else
thing = ""

Which is not nice because I'm doing twice the same instruction
or like :

m = re.match(r'define\s+(\S+)\s*{$', line)
if m:
thing = m.group(1)
else:
m = re.match(r'include\s+(\S+)$', line)
if m:
thing = m.group(1)
else
thing = ""

Which isn't nice neither because I'm going to have maybe 20 match
tests and I wouldn't like to have 20 indentations.

Anyone a recommendation?

Yes: Use an array of regular expressions and a loop (untested):

exprs = ["...",
"...",
]

thing = ""
for expr in exps:
m = re.match(expr, line)
if m:
thing = m.group(1)
break

Gary Herron
 
S

samb

Thanks for all those suggestions.
They are good!

1) Let's suppose now that instead of just affecting "thing =
m.group(1)", I need to do a piece of logic depending on which match I
entered...

2) Concerning the suggestion :
m = re.match(r'define\s+(\S+)\s*{$', line)
if m:
thing = m.group(1)

m = re.match(r'include\s+(\S+)$', line)
if m:
thing = m.group(1)

#etc...

It means that I'll do all the checks, even if the first one did match
and I know that the next will not...

Thanks again.
 
C

Chris Rebert

Thanks for all those suggestions.
They are good!
2) Concerning the suggestion :
m = re.match(r'define\s+(\S+)\s*{$', line)
if m:
   thing = m.group(1)

m = re.match(r'include\s+(\S+)$', line)
if m:
   thing = m.group(1)

#etc...

It means that I'll do all the checks, even if the first one did match
and I know that the next will not...

Note how I split it out into a separate function and used `return
m.group(1)` to avoid that exact situation.

Cheers,
Chris
 
S

samb

Note how I split it out into a separate function and used `return
m.group(1)` to avoid that exact situation.

Yes, you're right.
It's an interresting approach. I'll give it a try.

Cheers
 
S

samb

Hi,

I've found a work around, inspired from Rob Williscroft :

class ReMatch(object):
"""
Object to be called :
1st time : do a regexp.match and return the answer (args:
regexp, line)
2nd time : return the previous result (args: prev)
"""
def __call__(self, regexp='', line='', prev=False):
if prev:
return self.prev_match
self.prev_match = re.match(regexp, line)
return self.prev_match

re_match = ReMatch()

if re_match(r'define\s+(\S+)\s*{$', line):
m = re_match(prev=True)
# do some logic with m
elif re_match(r'include\s+(\S+)$', line):
m = re_match(prev=True)
# do some logic with m
else
# do some logic

Hope this is efficient ... I guess yes.

Cheers,
Sam
 
P

Peter Otten

samb said:
I've found a work around, inspired from Rob Williscroft :

class ReMatch(object):
"""
Object to be called :
1st time : do a regexp.match and return the answer (args:
regexp, line)
2nd time : return the previous result (args: prev)
"""
def __call__(self, regexp='', line='', prev=False):
if prev:
return self.prev_match
self.prev_match = re.match(regexp, line)
return self.prev_match

re_match = ReMatch()

if re_match(r'define\s+(\S+)\s*{$', line):
m = re_match(prev=True)
# do some logic with m
elif re_match(r'include\s+(\S+)$', line):
m = re_match(prev=True)
# do some logic with m
else
# do some logic

Hope this is efficient ... I guess yes.

No; just accessing the prev_match attribute instead of passing a flag to the
__call__() method is more efficient and easier to read. I think the latter
is the relevant point...

Peter
 
B

Bruno Desthuilliers

samb a écrit :
Hi,

I've found a work around, inspired from Rob Williscroft :

class ReMatch(object):
"""
Object to be called :
1st time : do a regexp.match and return the answer (args:
regexp, line)
2nd time : return the previous result (args: prev)
"""
def __call__(self, regexp='', line='', prev=False):
if prev:
return self.prev_match
self.prev_match = re.match(regexp, line)
return self.prev_match

re_match = ReMatch()

if re_match(r'define\s+(\S+)\s*{$', line):
m = re_match(prev=True)
# do some logic with m
elif re_match(r'include\s+(\S+)$', line):
m = re_match(prev=True)
# do some logic with m
else
# do some logic

Hope this is efficient ... I guess yes.

A direct attribute access is cheaper than a method call, and makes for a
simpler API too:

class ReMatch(object):
match = None

def __call__(self, regexp, source):
self.match = re.match(regexp, source)
return self.match


re_match = ReMatch()

if re_match(r'define\s+(\S+)\s*{$', line):
m = re_match.match
# do some logic with m
elif re_match(r'include\s+(\S+)$', line):
m = re_match.match
# do some logic with m

My 2 cents...
 
J

Jean-Michel Pichavant

samb said:
Hi,

I've found a work around, inspired from Rob Williscroft :

class ReMatch(object):
"""
Object to be called :
1st time : do a regexp.match and return the answer (args:
regexp, line)
2nd time : return the previous result (args: prev)
"""
def __call__(self, regexp='', line='', prev=False):
if prev:
return self.prev_match
self.prev_match = re.match(regexp, line)
return self.prev_match

re_match = ReMatch()

if re_match(r'define\s+(\S+)\s*{$', line):
m = re_match(prev=True)
# do some logic with m
elif re_match(r'include\s+(\S+)$', line):
m = re_match(prev=True)
# do some logic with m
else
# do some logic

Hope this is efficient ... I guess yes.

Cheers,
Sam
What do you mean by efficient ? If you're talking about speed, make sure
you care about it before doing some optimization.
If you talk about readability then it is absolutely *not* efficient (to
my humble opinion).

define, include = re.match(r'define\s+(\S+)\s*{$', line),
re.match(r'include\s+(\S+)$', line)
if define:
# do some stuff
elif include:
# do some other stuff
else:
# hello world


If you then have some speed problem with that script, you'll start
caring about how to execute if faster by making sure that only necessary
calls to re.match are done.

match = re.match(r'(define)\s+(\S+)\s*{$', line) or
re.match(r'(include)\s+(\S+)$', line) # note that the second operand is
executed only if the first is None

if match.group(1) == 'define':
# do some stuff with match.group(2)

elif match.group(1) == 'include':
# do some other stuff with match.group(2)

else:
# hello world


JM
 
S

samb

What do you mean by efficient ? If you're talking about speed, make sure
you care about it before doing some optimization.
If you talk about readability then it is absolutely *not* efficient (to
my humble opinion).

define, include = re.match(r'define\s+(\S+)\s*{$', line),
re.match(r'include\s+(\S+)$', line)
if define:
    # do some stuff
elif include:
    # do some other stuff
else:
    # hello world

If you then have some speed problem with that script, you'll start
caring about how to execute if faster by making sure that only necessary
calls to re.match are done.

match = re.match(r'(define)\s+(\S+)\s*{$', line) or
re.match(r'(include)\s+(\S+)$', line) # note that the second operand is
executed only if the first is None

if match.group(1) == 'define':
    # do some stuff with match.group(2)

elif match.group(1) == 'include':
    # do some other stuff with match.group(2)

else:
    # hello world

JM

Hi,

Thanks Bruno for the simpler API!
And thanks Jean-Michel, your second suggestion is clearly the best I
see.

I meant efficient mainly in the readable aspect (important for future
maintenance) and secondary for speed of execution. For sure I didn't
want to run a regexp twice.

Regards,
Sam
 

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