Generators

Generators lazily yield the next number in a sequence.

With a list comprehension, that would look like this:

my_list = [x**x for x in range(1,4)] # This stores [1,4,9] in memory.

With a generator, it would look like this:

Generators repeatedly call next() on a generator and disregard all previously computed members.

my_list = (x**x for x in range(1,4)) # This is lazy
for i in my_list:
    print(i) # prints 1, 4, 9 in that order.

Generators have O(1) memory but are not computed at time of calling, they compute the next result when looping.