trying to match a string

Andrew Freeman alif016 at gmail.com
Sat Jul 19 21:14:08 EDT 2008


John Machin wrote:
> On Jul 20, 5:00 am, Andrew Freeman <alif... at gmail.com> wrote:
>   
>> Andrew Freeman wrote:
>>     
>>> John Machin wrote:
>>>       
>>>> A couple of points:
>>>> (1) Instead of search(r'^blahblah', ...) use match(r'blahblah', ...)
>>>> (2) You need to choose your end-anchor correctly; your pattern is
>>>> permitting a newline at the end:
>>>>         
>> I forgot to change search to match. This should be better:
>>
>> def match(var):
>>     if re.match(r'[LRM]*\Z', var):
>>         return True
>>     else:
>>         return False
>>     
>
> A bit wordy ...
>
> if blahblah:
>    return True
> else:
>    return False
>
> can in total generality be replaced by:
>
> return blahblah
>
>
>   
>> I was also thinking if you had a list of these items needing to be
>> verified you could use this:
>>     
>
> You could, but I suggest you don't use it in a job interview :-)
>
>   
>>  >>> l = ['LLMMRR', '00thLL', 'L', '\n']
>>     
>
> (1) Don't use 'L'.lower() as a name; it slows down reading as people
> need to fire up their mental parser to distinguish it from the result
> of 3 - 2
>
>   
>>  >>> out = []
>>  >>> map(lambda i: match(i)==False or out.append(i), l)
>>     
> (2) Read PEP 8
> (3) blahblah == False ==> not blahblah
> (4) You didn't show the output from map() i.e. something like [None,
> True, None, True]
> (5) or out.append(...) is a baroque use of a side-effect, and is quite
> unnecessary. If you feel inexorably drawn to following the map way,
> read up on the filter and reduce functions. Otherwise learn about list
> comprehensions and generators.
>
>   
>>  >>> print out
>> ['LLMMRR', 'L']
>>
>>     
>
> Consider this:
>
>   
>>>> import re
>>>> alist = ['LLMMRR', '00thLL', 'L', '\n']
>>>> zeroplusLRM = re.compile(r'[LRM]*\Z').match
>>>> filter(zeroplusLRM, alist)
>>>>         
> ['LLMMRR', 'L']
>   
>>>> [x for x in alist if zeroplusLRM(x)]
>>>>         
> ['LLMMRR', 'L']
>   

Thank you for the pointers!
(1) Depending on the typeface I totally agree, Courier New has a nearly 
indistinguishable 1 and l, I'm using Dejavu Sans Mono (Bitstream Vera 
based). I was just thinking of it as a generic variable name for some 
input. I'm fairly new to python and programming in general, it's more of 
a hobby.

(2-3) This is actually the first time I've used map, maybe I should not 
give extra examples, I was actually using it as a learning tool for 
myself. I'm very thankful the mailing list has such skilled 
contributers, such as yourself, but I assume that it can't hurt to give 
working code, even though the style is less than perfect.

(3) Personally I think map(lambda i: match(i)==False or out.append(i), 
l) is a little more readable than map(lambda i: not match(i) or 
out.append(i), l) even if "baroque", your use of filter is obviously 
much clearer than either.

(4) I highly doubt that this code was actually to be used in an 
interactive session, the False/True output was truncated intentionally, 
it's an obvious, but superfluous output (unless you were to rely on this 
by attaching it to a variable which might lead to sorting issues).

(5) Thank you very much, I've read of the filter and reduce functions, 
but haven't used them enough to recognize their usefulness.

I did realize that a list comprehension would be useful, but wanted to 
try map()
I put together a generic matcher that returns either a list of True data 
(if the input is a list or tuple) or a boolean value:

def match(ex, var):
    "ex is the regular expression to match for, var the iterable or 
string to return a list of matching items or a boolean value respectively."
    ex = re.compile(ex).match
    if isinstance(var, (list, tuple)):
        return filter(ex, var)
    else:
        return bool(ex(var))

I believe this is fairly clean and succinct code, it would help my 
learning immensely if you feel there is a more succinct, generic way of 
writing this function.
--
Andrew



More information about the Python-list mailing list