Generators

Generator Function Basics

  1. # generator with yield
  2. def count_up_to(n):
  3. count = 1
  4. while count <= n:
  5. yield count
  6. count += 1
  7. for num in count_up_to(3):
  8. print(num)
  9. #ans: 1, 2, 3

Yield vs Return

  1. # yield pauses function
  2. def simple_gen():
  3. yield 1
  4. yield 2
  5. yield 3
  6. gen = simple_gen()
  7. next(gen)
  8. #ans: 1
  9. next(gen)
  10. #ans: 2

Generator is Iterator

  1. # generator is an iterator
  2. def my_gen():
  3. yield 1
  4. yield 2
  5. gen = my_gen()
  6. next(gen)
  7. #ans: 1
  8. #ans: can only iterate once
  9. list(gen)
  10. #ans: [2]
  11. list(gen)
  12. #ans: []

Infinite Generator

  1. # infinite sequence
  2. def infinite_counter():
  3. count = 0
  4. while True:
  5. yield count
  6. count += 1
  7. #ans: use with break or take first n
  8. counter = infinite_counter()
  9. for i, num in enumerate(counter):
  10. if i >= 3:
  11. break
  12. print(num)
  13. #ans: 0, 1, 2

Generator with Condition

  1. # filter in generator
  2. def even_numbers(n):
  3. for i in range(n):
  4. if i % 2 == 0:
  5. yield i
  6. list(even_numbers(10))
  7. #ans: [0, 2, 4, 6, 8]

Yield From

  1. # delegate to another generator
  2. def generator1():
  3. yield 1
  4. yield 2
  5. def generator2():
  6. yield from generator1()
  7. yield 3
  8. list(generator2())
  9. #ans: [1, 2, 3]

Exercises - Part 1

  1. # what is returned?
  2. def gen():
  3. yield 1
  4. result = gen()
  5. type(result)
  6. #ans: <class 'generator'>

Exercises - Part 2

  1. # yield in loop?
  2. def gen():
  3. for i in range(3):
  4. yield i
  5. list(gen())
  6. #ans: [0, 1, 2]

Exercises - Part 3

  1. # generator exhaustion?
  2. def gen():
  3. yield 1
  4. yield 2
  5. g = gen()
  6. next(g)
  7. #ans: 1
  8. next(g)
  9. #ans: 2
  10. next(g)
  11. #ans: StopIteration

Exercises - Part 4

  1. # multiple yields?
  2. def gen():
  3. yield 1
  4. yield 2
  5. return 3
  6. list(gen())
  7. #ans: [1, 2] (return value ignored)

Exercises - Part 5

  1. # generator vs list?
  2. def gen():
  3. yield 1
  4. list(gen())
  5. #ans: [1]
  6. gen()
  7. #ans: <generator object>

Exercises - Part 6

  1. # fibonacci generator?
  2. def fib(n):
  3. a, b = 0, 1
  4. for _ in range(n):
  5. yield a
  6. a, b = b, a + b
  7. list(fib(5))
  8. #ans: [0, 1, 1, 2, 3]

Exercises - Part 7

  1. # yield from list?
  2. def gen():
  3. yield from [1, 2, 3]
  4. list(gen())
  5. #ans: [1, 2, 3]

Exercises - Part 8

  1. # generator with return?
  2. def gen():
  3. yield 1
  4. return 2
  5. g = gen()
  6. next(g)
  7. #ans: 1
  8. next(g)
  9. #ans: StopIteration (with value 2)

Exercises - Part 9

  1. # send to generator?
  2. def gen():
  3. value = yield
  4. print(value)
  5. g = gen()
  6. next(g) # prime
  7. g.send("Hello")
  8. #ans: prints "Hello"

Exercises - Part 10

  1. # generator memory?
  2. def gen():
  3. for i in range(1000000):
  4. yield i
  5. #ans: memory efficient (lazy)
  6. lst = [i for i in range(1000000)]
  7. #ans: all in memory at once

Google tag (gtag.js)