[Python-Dev] dict.sortedkeys()

Robert Brewer fumanchu at amor.org
Mon Apr 19 12:43:07 EDT 2004


Alex Martelli wrote:
> On Saturday 17 April 2004 10:21 pm, Robert Brewer wrote:
>    ...
> > Yes, of course. But I'm working on a large business app 
> framework. That
> > means either:
> >
> > 1. Writing sorted into every module where it's needed.
> > 2. Putting sorted into a package somewhere, which makes it 
> longer and
> > uglier with absolute referencing.
> > 3. Customizing consumers' Python install.
> >
> > ...none of which are good options.
> 
> Is sorted the ONLY "utility" function your LARGE business app 
> framework needs in addition to what comes with Python 2.3?  
> That would really be utterly astounding to me.

That would astound me, too. :) However, I will make the following points
(if only for posterity--this is getting off-topic):

1. Despite what I just said, Python 2.3 is astoundingly complete.

2. Although I suck at actual implementation, I can be a pretty good
designer. I'd say 95% of the "utility" functions I write end up being
specific to one of the (sub)packages in such a framework, so it's
logical to shove them in that package.

3. I just checked; I have 4 "utility" modules that the framework uses:
one consists of 3 dict subclasses, another has a couple date tools, one
provides first-class expressions, and finally, there's a small import
helper.

Now that I've written that out, I wonder how many other people have
similar, generic, yet custom-built code. Which leads me to wonder if a
survey on c.l.p. would help hone direction for some standard lib
development.

> The only truly unacceptable alternative, in my opinion,
> is to repeat the coding for the utility functions more
> than once: as long as they're coded _once, and only once_,
> I'm a pretty happy camper.

Yep. There's nothing like forgetting to update both copies to make you
wish you had only done it once the first time. :)

> These days, I far prefer to code, more simply:
> 
> import __builtin__
> # get error msg in case of conflict
> assert not hasattr(__builtin__, 'ut')
> import utils as ut
> __builtin__.ut = ut
> 
> and access the utilities from everywhere as ut.sorted, 
> ut.scrambled, etc, etc.
> ONE relatively mysterious barename is OK...

That runs counter to my sensibilities as a Modern. I have to have clean
containers; a module named "utils" starts to cross the line between
practicality and purity. I much prefer to group similar code into
multiple modules which then get placed in site-packages. Again, if they
are app-specific, they go in the __init__.py for the app. The leap from
ZERO mysterious barenames to ONE is larger than the leap from one to
two, for me at least. ;)

> The "trickle" of neat utility functions into Python's
> built-ins, by itself, will not entirely solve the
> problem for you, IMHO.

No; I don't expect it to. I use the alternatives all the time. But there
comes a point when the cost of the neat function (implemented in any way
other than a builtin) outweighs the cost of the normal "boilerplate"
method of doing it.

sorted() is just such a case--*extremely* generic and also greatly
useful in making code clear and succinct. If you could sort a
dictionary's keys in three lines of code by saying:

keys
sort
iterate

there wouldn't be a problem, because the cost to the brain and fingers
of the programmer is low. But in pre-2.4 one must write:

dkeys = mydict.keys()
dkeys.sort()
for key in dkeys:

...which is extremely costly in terms of usability. Compare to:

for key in sorted(mydict):

Wow. What a difference. Design of a language is not that different from
any other design task: you want to make a better product the easiest
choice for the user. Small changes like the above end up returning many
times their investment.


Robert Brewer
MIS
Amor Ministries
fumanchu at amor.org



More information about the Python-Dev mailing list