Reading List Comprehension?

Skip Montanaro skip at mojam.com
Thu Sep 7 10:18:48 EDT 2000


    Stephen> But..list comprehensions.. I can't quite fathom.

    --> x for subseq in seq for x in subseq
 
    Stephen> Eh?!?! That looks so..wrong. No whitespace, parens, no nothing,
    Stephen> with all those keywords mixed in there. I can't pronounce it,
    Stephen> or make any sense outat it. Maybe that's because the examples
    Stephen> insisted upon using exponential syntax, instead of something
    Stephen> simple like addition. :)

Stephen,

Like most new features, I suspect list comprehensions will take some time to
get used to and that people will initially be more comfortable with simpler
uses.  To visually parse a list construction, look for 'for' and 'if'.  You
can mentally but a comma in front of these keywords (though I'm not sure the
Python parser would have allowed that):

    instead of	    [x**2 for x in range(25) if x%2]
    read it as	    [x**2, for x in range(25), if x%2]

If you are looking for more concrete visual cues, you might try adding a
newline in front of 'for' and if':

    [x**2
      for x in range(25)
        if x%2]

A few simple examples may help.

* list of squares less that 25**2:

    >>> [x**2 for x in range(25)]
    [0, 1, 4, 9, ...etc...]

* list of squares of odd numbers less than 25**2:

    >>> [x**2 for x in range(25) if x%2]
    [1, 9, 25, ...etc...]

* list of whitespace stripped strings:

    >>> strings = ["apple ", "  banana ", "passion fruit"]
    >>> [x.strip() for x in strings]
    ['apple', 'banana', 'passion fruit']

* list of all strings in a list where the string contains an 'o':

    >>> [x for x in strings if 'o' in x]
    ['passion fruit']

As one final example, here's a simple list sort that uses list
comprehensions.  (Note that its behavior is not the same as the sort method
of lists, since it returns a new list.)

    def sort(l):
	if len(l) <= 1:
	    return l
	b,l = l[0],l[1:]
	return (sort([a for a in l if a < b]) +
		[b] +
		sort([c for c in l if c >= b]))

    if __name__ == "__main__":
	import random
	l = []
	for i in range(17):
	    l.append(random.randrange(100))
	l2 = l[:]
	print "before:", l
	l = sort(l)
	print "after: ", l

	# compare result with list's sort method
	l2.sort()
	print "sorted correctly?", (l == l2) and "yes" or "no"




More information about the Python-list mailing list