## List Comprehensions and Generators

Producing lists using a for loop in conjunction with range() is easy. In addition, Python provides an alternative approach called list comprehensionsâ€”these are expressions that generate lists. (Note that this and other advanced sections in

Parts I, II, and III, are indicated by a rocket in the margin. You can skip these on first reading since back-references are given where appropriate.)

Let us generate a list of numbers divisible by 5:

fives.append(x) # fives = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]

This involves the familiar combination of for and range().

Now we will see how to generate a simple list of consecutive numbers using a list comprehension:

This produces the list [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]. List comprehensions can have conditions attached:

This generates the same fives list as our original for loop. More complex list comprehensions with nested for loops are perfectly possible, although the more conventional syntax may be easier to read in such cases.

One drawback of list comprehensions is that they generate the entire list in one go, which can consume a lot of memory if the list is very large. This problem also applies to the conventional syntax, but you can get around it by using xrange() instead of range(). Python generators provide another solution. These are expressions that work like list comprehensions, except that they generate their lists lazily.

This is almost identical to the list comprehension (the only obvious difference being the use of parentheses rather than square brackets), but the object returned is not a list! Instead, a generator is returned. A generator is an iterator, so we can do things like this:

for x in (x for x in range(50) if x % 5 == 0): print x, which will print "0 5 10 15 20 25 30 35 40 45".

List comprehensions are not strictly necessary in Python programming; the coverage here is mostly to ensure that they are recognizable when reading other people's code, and to provide a taste of some of Python's more advanced features. When we use them later on, we will generally show equivalent code that uses for loops, for example. On the other hand, generators, although an advanced and relatively new feature of Python, cannot easily be mimicked. We will create a simple generator function in the next section, and some very short generator methods in an example class in Chapter 3.