Iterating over a dictionary's sorted keys

Philip 'Yes, that's my address' Newton nospam.newton at gmx.li
Thu May 25 00:20:08 EDT 2000


Hi there,

In the other P language, the standard idiom is

    for $key (sort keys %d) { ... }                # (1)

The naive approach in Python would be

    for key in d.keys().sort(): pass               # (2)

However, this doesn't make sense (I realise this). I presume that this
makes a temporary list containing the keys of d, sorts this list, throws
the list away and then does the equivalent of 'for k in None: pass'.

_Learning Python_ suggests the following in its solution to example 3 of
chapter 3:

    keys = d.keys
    keys.sort()
    for key in keys: pass # whatever               # (3)

Is there any way to avoid this temporary variable and to write the for
in one line?

One attempt at this was

    for key in (k=d.keys(); k.sort(); k): pass     # (4)

however, this is invalid syntax, as is

    for key in (k=d.keys(), k.sort(), k): pass     # (5)

, presumably because you can't use assignment as an expression in Python
and because C's comma operator doesn't exist in Python because it would
be confused with the tuple-making comma.

Next attempt was

    for key in lambda k=d.keys(): k.sort(), k: pass # (6)

-- again, no comma operator (and lambdas can contain only one statement;
is that right?).

    for key in (lambda k=d.keys(): k.sort() or k): pass # (7)

Devious: Python's or returns the last true object evaluated, not just 1
or 0. So k.sort() (returning None) causes the right-hand-side of the or
to be evaluated and k to be returned from the lambda. But I forgot to
call the lambda! (I found this out by writing the lambda by itself on
the command line and found that the interpreter printed it as "(function
<lambda> at .....)".)

    for key in (lambda k=d.keys(): k.sort() or k)(): print key, # (8)

Is there no easier way than (8) to iterate over a dictionary's sorted
keys in one line, or without invoking temporary variables? It looks sort
of ridiculous to have to go to such lengths, especially since this
operation must be fairly common.

What's the standard Python idiom for this? What do you use?

Cheers,
Philip
-- 
Philip Newton <nospam.newton at gmx.li>
If you're not part of the solution, you're part of the precipitate.



More information about the Python-list mailing list