re Challenge: More Compact?

Tim Peters tim.one at home.com
Sun Jul 15 21:36:22 EDT 2001


[Tim Hammerquist]
> ...
> 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

Well, it's un-Pythonic to try to emulate Perl undef via Python None; it's
idiomatic to return 0 for false and 1 for true, in which case the last three
lines can be replaced by, e.g.,

    return max(elements) < 256

Note that the leading "^" in the Python regexp isn't needed (can save
another entire character that way <wink>).

The Python version should also check for match failure.  Like

def valid_ip(ip):
    m = re.match(r'(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$', ip)
    if m:
        elements = map(int, m.groups())
        return max(elements) < 256
    return 0

Yes, you can squash lines out of that -- I wouldn't.

BTW, does it bother anyone that all of these solutions accept an IP ending
with a newline?

regexps-are-surprising-ly y'rs  - tim





More information about the Python-list mailing list