re Challenge: More Compact?

Mon Jul 16 06:06:01 CEST 2001

```On Mon, 16 Jul 2001 00:58:46 GMT, tim at vegeta.ath.cx (Tim Hammerquist) wrote:

> Easily implemented in Perl:
>
> : sub valid_ip {
> :     my (\$ip, \$failed, @elements) = (shift, 0);
> :     @elements = (\$ip =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\$/);
> :     \$failed = grep { \$_ > 255 } @elements;
> :     return (\$failed) ? undef : 1;
> : }
>
> Slightly more verbose in Python:
>
> : import re
> : def valid_ip(ip):
> :     expr = r'^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\$'
> :     elements = map(int, re.match(expr, ip).groups())
> :     failed = filter(lambda x: x > 255, elements)
> :     if failed:  return None
> :     else:       return 1

In the interest of "fair" Python/Perl comparisons:

: import re
: def valid_ip(ip):
:     expr = r'^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\$'
:     elements = map(int, re.match(expr, ip).groups())
:     failed = filter(lambda x: x > 255, elements)
:     return !failed

Exactly the same as the Perl version.

the "import re" line is offset by Python doing parameter passing
itself, and all the rest correspond line-for-line.
Of course, using list-comps, it might be easier:

: import re
: def valid_ip(ip):
:     expr = r'^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\$'
:     failed = [x if int(x)>255 for x in re.match(expr, ip).groups()]
:     return !failed

Of course, I would never write that way -- here's more idiomatic Python:

: import re
: valid_ip_re = re.compile(r'^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\$')
: def valid_ip(ip):
:    match = valid_ip_re.match(ip)
:    if not match:
:        return
:    return ![x if int(x)>255 for x in match.groups()]

And now it's even correct!
--
gpg --keyserver keyserver.pgp.com --recv-keys 46D01BD6 54C4E1FE
Secure (inaccessible): 4BD1 7705 EEC0 260A 7F21  4817 C7FC A636 46D0 1BD6
Insecure (accessible): C5A5 A8FA CA39 AB03 10B8  F116 1713 1BCF 54C4 E1FE

```