Perl is worse!

Alex Martelli alex at magenta.com
Sat Jul 29 06:57:01 EDT 2000


"Steve Lamb" <grey at despair.rpglink.com> wrote in message
news:slrn8o4aid.7dm.grey at teleute.rpglink.com...
> On Fri, 28 Jul 2000 19:29:52 -0400, Karl Ulbrich <kulbrich at yahoo.com>
wrote:
> >If they already contained numbers (well, strings of digits), and you were
> >certain, then simply:
>
> > a = int(b)
>
>     As stated, that would work except Python returns a None on a no-match
and

Incidentally, you can change that if you wish -- it ain't hard!  See:

>>> re.match('a(\d+)|b(\d+)','a3').groups()
('3', None)

but:

>>> re.match('a(\d+)|b(\d+)','a3').groups('0')
('3', '0')

None is the DEFAULT returned for nonmatching groups, but if
you don't like that, the argument to the groups method of
the match object is just the ticket.


> None can't be converted.

No, but '0' easily can, and as we've seen it's very easy
to arrange for groups to return that if so desired.  So,
to summarize...:

>>> there = re.compile('a(\d+)|b(\d+)')
>>> map(int, there.match('a3').groups('0'))
[3, 0]
>>> map(int, there.match('b4').groups('0'))
[0, 4]

I do not think this need be the best approach to the
specific problem you've stated, but it's surely one
approach to keep in mind.  0 rather than '0' as the
argument to groups would work just as well, btw, since
int(0) and int('0') both evaluate to 0...:-).

So, an alternative implementation of the function I
already proposed, and here repeat...:

def intGroups(match, default=0):
    results = []
    for g in match.groups():
        if g: results.append(int(g))
        else: results.append(default)
    return results

would be:

def intGroups(match, default=0):
    return map(int, match.groups(default))


It's certainly more concise, and most likely faster,
too, but readability is debatable.  If one just does
not like map, a middle of the road alternative:

def intGroups(match, default=0):
    results = []
    for g in match.groups(default):
        results.append(int(g))
    return results

You see, even in Python tmtowtdi -- we just don't
_emphasize_ that:-).  The ideal would be to have
ONE obvious way to do it -- although the 'obvious'
part may not be obvious until you know the language
and standard library pretty well:-).  In that light,
I suspect the Obvious Way here is yet another:

def intGroups(match, default=0):
    matches = match.groups(default)
    return map(int, matches)

Clearly equivalent to the one-liner, but, by giving
a name to the tuple returned by groups, albeit a
local and quite transient one, we give it, I feel,
just the light-touch sort of emphasis it deserves
here -- a 'subdued highlight', if you'll pardon the
oxymoron, that seems to me to make it very readable...
and to suggest all sorts of useful generalizations,
such as, say:

def translatedGroups(match, translate=int, default=0):
    matches = match.groups(default)
    return map(translate, matches)

intGroups=translatedGroups


Note that I've provided a synonym for the most likely
usage with the binding right after the def -- another
useful idiom, I believe.


Alex






More information about the Python-list mailing list