Saturday, January 31, 2015

Overview

In python, it’s common to see something like for _ in range(10). This says loop 10 but it also creates a list of 10 elements. If you replace the 10 with 1000000, it will create a very large list and take up all the memory for nothing. Instead, you could use a generator. A generator is like a pause and continue on a method and it improves the space complexity of your code. More information about generators can be found here.

A generator comprehension is the lazy version of a list comprehension. It is just like a list comprehension except that it returns an iterator instead of the list ie an object with a next() method that will yield the next element.

Imagine you want to sum up all the numbers from 0 to 1000000. It would look something like this.

1
2
3
4
5
6
7
8
def firstn(n):
     num, nums = 0, []
     while num < n:
         nums.append(num)
         num += 1
     return nums

sum_of_first_n = sum(firstn(1000000))

The equivilant generator will look like this.

1
2
3
4
5
6
7
def firstn(n):
    num = 0
    while num < n:
        yield num
        num += 1

sum_of_first_n = sum(firstn(1000000))

You can also create generator comprehensions.

1
2
3
4
5
6
7
8
9
10
11
12
# normal list comprehension
my_list = [1, 3, 5, 9, 2, 6]
filtered_list = [item for item in my_list if item > 3]
print(filtered_list) # [5, 9, 6]


# generator comprehension
filtered_gen = (item for item in my_list if item > 3)
# you can use it in a `for in` loop
# or you can pass it to the list constructor
gen_to_list = list(filtered_gen)
print(gen_to_list) # [5, 9, 6]

Random Posts