Re: affectation in if statement
On Mar 16, 11:56 am, Jean-Michel Pichavant wrote: > samb wrote: > > 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 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 -- http://mail.python.org/mailman/listinfo/python-list
Re: affectation in if statement
samb wrote: 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 -- http://mail.python.org/mailman/listinfo/python-list
Re: affectation in if statement
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... -- http://mail.python.org/mailman/listinfo/python-list
Re: affectation in if statement
samb wrote: > 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 -- http://mail.python.org/mailman/listinfo/python-list
Re: affectation in if statement
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 -- http://mail.python.org/mailman/listinfo/python-list
Re: affectation in if statement
On Mar 16, 9:53 am, Chris Rebert wrote: > On Tue, Mar 16, 2010 at 1:37 AM, samb wrote: > > 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... > > 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 -- http://mail.python.org/mailman/listinfo/python-list
Re: affectation in if statement
samb wrote in news:5c361012-1f7b-487f-915b-0f564b238be3 @e1g2000yqh.googlegroups.com in comp.lang.python: > 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... > Ths is how I did it when I had the need: class ReMatch( object ): def __call__( self, pat, string ): import re self.match = re.match( pat, string ) return self.match is not None clip = ... re = ReMatch() if re( r'\s*TM(\d+)', clip ): ... elif re( r'\s*(https?://.*)', clip ): ... elif re( r'\d{12}$', clip ): ... Rob. -- -- http://mail.python.org/mailman/listinfo/python-list
Re: affectation in if statement
On Tue, Mar 16, 2010 at 1:37 AM, samb wrote: > 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 -- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
Re: affectation in if statement
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. -- http://mail.python.org/mailman/listinfo/python-list
Re: affectation in if statement
samb wrote: 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 Thanks! Gary Herron -- http://mail.python.org/mailman/listinfo/python-list
Re: affectation in if statement
samb writes: > 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) ... -- http://mail.python.org/mailman/listinfo/python-list
Re: affectation in if statement
On Tue, Mar 16, 2010 at 12:45 AM, samb wrote: > 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 -- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
affectation in if statement
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! -- http://mail.python.org/mailman/listinfo/python-list