def count_up(n):
i = 0
while i < n:
yield i
i += 1
for num in count_up(5):
print(num, end=' ') # 0 1 2 3 4
# Returns a generator object, NOT a list!
print(type(count_up(5))) # <class 'generator'>def first_n(n):
result = []
for i in range(n):
result.append(i ** 2)
return result # Returns FULL list at once
def first_n_gen(n):
for i in range(n):
yield i ** 2 # Yields ONE value at a time
print(first_n(5)) # [0, 1, 4, 9, 16]
print(first_n_gen(5)) # <generator object>
print(list(first_n_gen(5))) # [0, 1, 4, 9, 16]# List comprehension — builds entire list in memory
squares_list = [x**2 for x in range(1000000)] # ~8MB
# Generator expression — lazy, ~0MB
squares_gen = (x**2 for x in range(1000000)) # ~0MB
print(sum(squares_gen)) # Consumes values one by onedef upper_letters():
yield from 'ABCDE'
def lower_letters():
yield from 'abcde'
def all_letters():
yield from upper_letters()
yield from lower_letters()
print(list(all_letters())) # ['A','B','C','D','E','a','b','c','d','e']def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
import itertools
print(list(itertools.islice(fibonacci(), 10)))
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]def accumulator():
total = 0
while True:
value = yield total
if value is not None:
total += value
gen = accumulator()
next(gen) # Prime the generator (returns 0)
print(gen.send(10)) # 10
print(gen.send(20)) # 30
print(gen.send(5)) # 35Create a generator function `prime_numbers()` that yields prime numbers infinitely. Create a generator function `take(n, gen)` that yields only the first n values from any generator using yield from with islice. Create a generator expression `even_squares` that yields squares of even numbers from 0-20. Demonstrate: first 10 primes, even_squares as a list, and a pipeline where you filter primes > 100.