Python's simplicity philosophy

Andrew Dalke dalke at dalkescientific.com
Sun Nov 16 13:28:10 EST 2003


Moshe:
> This would probably be done by what I might call DMU
> (Decorate-Maximize-Undecorate) --


> def longest(seq):
>     return max([(len(x),x) for x in seq])[1]


Almost.   Your code requires that the 'x' be comparable,
eg, suppose it's a sequence of complex numbers and the
goal is to find a number with largest imaginary component.
Then the following won't work

def largest_imaginary(complex_seq):
     return max([(x.imag, x) for x in complex_seq])[1]

There's also the worry that your code breaks ties
by looking for the max object, when the one I spec'ed
said I chose the first match.


To fix these you would need to write your DMU as

def longest(seq):
   return max([ (len(x), -i, x) for x, i in enumerate(seq) ])[2]

which is identical (for obvious reasons) in style to
the Decorate-Stable-Sort-Undecorate idiom.  ("-i" done
to get the first match.)

Is such a thing common enough to warrant a new function
somewhere in the standard library?  Here are existing
use cases (I'll use 'maxitem' as the function name):

CGIHTTPServer.py:  nobody = 1 + max(map(lambda x: x[2], pwd.getpwall()))
could be replaced with
   nobody = 1 + maxitem(pwd.getpwall(), lambda x: x[2])

Slightly fewer characters, but requires knowing more of the
standard library, and here the extra guarantees of "maxitem"
aren't needed

That's the only example I could find in the std. lib which
uses a min or max on a map.

I also looked for a 'for .* in ' followed within 6 lines
by a ' > ' or ' < ' and only found this example from trace.py

     longest = ""
     for dir in sys.path:
         if path.startswith(dir) and path[len(dir)] == os.path.sep:
             if len(dir) > len(longest):
                 longest = dir

which could not be easily replaced with your max-of-a-list
because of the filter and default value of "".  It could
be written using "maxitem" as

   longest = maxitem(
       [dir for dir in sys.path if
                 path.startswith(dir) and path[len(dir)] == os.path.sep],
       len, "")

However, I find that to be harder to understand than the
original code and not significantly shorter.

Therefore I find there to be few cases in the standard
library which would be improved with a standard "DMU"
function.  That doesn't mean it shouldn't be added,
only that the decision has little hard data to back
up a gut feeling.

					Andrew
					dalke at dalkescientific.com






More information about the Python-list mailing list