Archived

generator expressions

An old note — I haven't updated it since I wrote it.

Generator Expressions are very similar to List Comprehensions, the main difference being they evaluate lazily at runtime.

Let's compare the output of this code, using a List Comprehension:

 1def print_eval(x):
 2    print('eval!')
 3    return x
 4
 5LC = [print_eval(x) for x in [1,2,3,4,5]]
 6
 7print("Starting loop")
 8
 9for v in LC:
10    print(v)
11
12"""
13Output:
14
15eval!
16eval!
17eval!
18eval!
19eval!
20Starting loop
211
222
233
244
255
26"""

Now using a Generator Expression:

 1def print_eval(x):
 2    print('eval!')
 3    return x
 4
 5GE = (print_eval(x) for x in [1,2,3,4,5])
 6
 7print("Starting loop")
 8
 9for v in GE:
10    print(v)
11
12"""
13Starting loop
14eval!
151
16eval!
172
18eval!
193
20eval!
214
22eval!
235
24"""

This has the wonderful advantage that no extra memory is required to store the result of the List Comprehension. However, do bear in mind that Generator Expressions do have their own mechanisms that also carry their own overheads. Carefully profiling your code may be required.

Q: Given an input array A = [1,4,5,7,8,9] take the sum of elements greater than 5

Solution

1A = [1,4,5,7,8,9]
2sum(x for x in A if x > 5)
3# result: 24