Every Python programmer would be familiar with list comprehension. List comprehension is a very useful, brilliant feature of Python, which allows complex list constructions in a concise and easy way. For example, to construct a list of squares of integers from 1 to 10, we can write:
l = [ x**2 for x in range(1,11) ]
More complex constructions can be used, for example with an if-condition.
Today, I learned the mechanism behind list comprehension in Python. It is indeed more flexible and more powerful beyond list construction. When we write a list comprehension statement, a generator is created, which will yield the items one by one. In particular, when we write
it = ( x**2 for x in range(1,11) )
it is a generator that generates the squares of integers from 1 to 10. The original list comprehension simply creates a list from items of this generator. However, the generator created this way can be used anywhere a generator is accepted, for example with functions like
zip, and many more. For instance, to take the sum of all squares of integers from 1 to 100, the following are equivalent:
print sum([x**2 for x in range(1,101)]) print sum( x**2 for x in range(1,101) )
However, the latter is faster and requires less memory than the first, at least in theory, because it does not need to construct a temporary full list of squares. Instead, it works directly with the generator. Note that to create a tuple of these squares, we write
mytuple = tuple( x**2 for x in range(1,101) )
mytuple = ( x**2 for x in range(1,101) )
since the latter will return a generator, not a tuple.
More information can be found here.