list comprehensions: sorting?

Alex Martelli aleax at aleax.it
Thu Sep 6 03:52:08 EDT 2001


"Clark C . Evans" <cce at clarkevans.com> wrote in message
news:mailman.999736326.13453.python-list at python.org...
> As an SQL junkie... I've gotten addicted to
> list comprehensions like... especially in
> list of tuples...
>
>  [process(x) for x in mylist if x[4]
>
> I read the above as something like...
>
>  SELECT process(x) FROM mylist AS x WHERE x[4]

Nice framing, and makes your wish quite understandable.
A list comprehension can have one or more occurrences
of 'for' and zero or more of 'if', but you might mostly
frame those as joins:-).


> That's ok... but I'd like to have a nicer way
> to say "sort by column #2" ; preferably as part
> of the longer expression...
>
>  [process(x) for x in list if x[4] sortdesc x[2] ]

Alas, that's not really doable - because the list
comprehension is defined to have the semantics of:

    temp = []
    for x in list:
        if x[4]:
            temp.append(process(x))
    return temp

where would the new 'sortdesc' keyword fit in this
model?


> Where "sortdesc" is an expression that I want the
> list sorted by descending.  This would make my code
> much more readable...
>
> Thoughts?  Any better alternative to what I'm
> writing above?

Well, what about:

    map(process, sorted_by(2,
        [x for x in mylist if x[4]], descend=1))

...?  You'd have to map the process function AFTER
sorting, since the hypothetical sorted_by could
only work on the values of the list it's given.

If this is OK for you, then sorted_by is easy
to write:

def sorted_by(col, alist, descend=0):
    temp = [(x[col],x) for x in alist]
    temp.sort()
    if descend: temp.reverse()
    return temp

and not too hard to generalize in various different
ways if you need a bit more generality (sort on
several columns, make the sort stable -- e.g see
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52234
for stable-sorting via this kind of idiom).


Alex






More information about the Python-list mailing list