comprehending comprehensions

Skip Montanaro skip at pobox.com
Sat Jun 14 21:33:02 EDT 2003


    maurix> def qsort(list) :
    maurix>     if len(list)<=1 : return list
    maurix>     x,xs=list[0],list[1:]
    maurix>     elts_lt_x=[y for y in xs if y < x]
    maurix>     elts_greq_x=[y for y in xs if y >= x]
    maurix>     return qsort(elts_lt_x)+[x]+qsort(elts_greq_x)

    maurix> 6 lines vs 5 lines, not bad!
    maurix> Someting can do it better??

The temporary list comprehensions aren't really needed:

def qsort(lst):
    if len(lst) <= 1: return lst
    x, xs = lst[0], lst[1:]
    return (qsort([i for i in xs if i<x]) + [x] +
            qsort([i for i in xs if i>=x])

and if you're willing to forego a little bit of white space:

def qs(lst):
    if len(lst) <= 1: return lst
    x, y = lst[0], lst[1:]
    return qs([i for i in y if i<x])+[x]+qs([i for i in y if i>=x])

Eliminating x and y then crushing a bit more white space:

def qs(l):
 if len(l) <= 1: return l
 return qs([i for i in l[1:]if i<l[0]])+l[:1]+qs([i for i in l[1:]if i>=l[0]])

Finally, the ultimate abuse:

def qs(l):
 return len(l) > 1 and (qs([i for i in l[1:]if i<l[0]])+l[:1]+qs([i for i in l[1:]if i>=l[0]])) or l

Of course, these are all just variations on the theme you posted.

>>> def qs(l):
...  return len(l) > 1 and (qs([i for i in l[1:]if i<l[0]])+l[:1]+qs([i for i in l[1:]if i>=l[0]])) or l
... 
>>> import random
>>> import string
>>> l = list(string.letters)
>>> random.shuffle(l)
>>> "".join(l)
'CIaSFXhqQYuvDPsxVNUbepnjHmOiMdBkoRWtZwcKGzAgErfJLylT'
>>> "".join(qs(l))
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'

Skip





More information about the Python-list mailing list