While we're talking about annoyances

Alex Martelli aleax at mac.com
Wed May 2 10:49:54 EDT 2007


Michael Hoffman <cam.ac.uk at mh391.invalid> wrote:

> Steven D'Aprano wrote:
> > On Wed, 02 May 2007 06:10:54 +0000, Tim Roberts wrote:
> 
> >> I've tended to favor the "Schwarzian transform" (decorate-sort-undecorate)
> >> because of that.
> > 
> > That's what the key= argument does. cmp= is slow because the comparison
> > function is called for EVERY comparison. The key= function is only called
> > once per element.
> 
> Right. Using sort(key=keyfunc) is supposed to be faster than 
> decorate-sort-undecorate. And I think it is clearer too.

Right, and speed comparisons are pretty easy (just make sure to copy the
list within the loop to compare like with like:-)...:

brain:~ alex$ python -mtimeit -s'L=range(-3,5)' 'X=L[:]; X.sort(lambda
x, y: cmp(abs(x), abs(y)))'
100000 loops, best of 3: 13 usec per loop

brain:~ alex$ python -mtimeit -s'L=range(-3,5)' 'X=[(abs(x),x) for x in
L]; X.sort(); X=[x for _,x in X]'
100000 loops, best of 3: 7.85 usec per loop

brain:~ alex$ python -mtimeit -s'L=range(-3,5)' 'X=L[:];
X.sort(key=abs)'     
100000 loops, best of 3: 4.23 usec per loop

The "intrinsic" DSU done by key= is clearly superior on all scores.

The semantics are subtly different: it guarantees to never compare
anything _except_ the key (because that's typically what one wants), so,
make sure they key includes everything you may ever want compared.


Alex





More information about the Python-list mailing list