In [15]:
# generators are iterable objects that return successive values on demand
# instead of storing them all like a list.
# there are two ways to make generators. first, generator comprehensions
g = (x for x in range(10))
g
Out[15]:
In [18]:
g.next()
In [19]:
# the second one is using "yield" instead of "return" in a function
def gen_range(n):
for i in range(n):
yield i
g = gen_range(10)
g
Out[19]:
In [30]:
g.next()
In [27]:
# a generator is iterable, but only once after which it is used up
g = gen_range(2)
for i in g:
print i
In [28]:
for i in g:
print i
In [31]:
# "yield" can occur anywhere in a function
def gen_range(n, before=0, after=0):
yield before
for i in range(n):
yield i
yield after
for x in gen_range(4, -1, -2):
print x
In [32]:
# if you want to store everything that a generator generates, use "list" or "tuple"
list(gen_range(5))
Out[32]:
In [33]:
tuple(gen_range(5))
Out[33]:
In [34]:
# indexing does not work on generators
gen_range(5)[0]
In [42]:
# but "in" does
g = gen_range(5)
75 in g
Out[42]:
In [134]:
# generators can run forever, so be very careful about converting them to lists or tuples;
# that will cause an infinite loop and your program will freeze
def count_forever():
n = 0
while True:
yield n
n = n + 1
if n == 8:
return
g = count_forever()
g
Out[134]:
In [144]:
g.next()