Need to sum a million squares without first storing a million numbers? A generator supplies values one at a time. It is an iterator: it produces the next value when requested rather than loading every value up front. section 7.4 section 7.4.1
Yield squares as they are needed
Set `upper_limit = 1_000_000`, then define `perfect_squares(limit)` with `n = 1` and a `while n <= limit` loop. Inside the loop, use `yield n * n`, followed by `n += 1`. Calling `squares = perfect_squares(upper_limit)` creates the generator; `sum(squares)` produces `333333833333500000`. Each `yield` pauses execution. The next request resumes after that `yield`, with `n` preserved. section 7.4.1
This on-demand behavior is a form of lazy evaluation. In the million-square comparison, the list reports a size of 8,448,712 bytes, while the generator reports 88 bytes. The generator retains its current state instead of storing the whole sequence. section 7.4 section 7.4.2
Use an expression for a simple sequence
`squares = (x * x for x in range(1, 5))` creates a generator without a separate function. `next(squares)` returns `1`; `sum(squares)` then returns `29`, not `30`, because the first value has already been consumed. For a one-off calculation, write `sum(x * x for x in range(1, 5))` instead. Parentheses distinguish a generator expression from a list comprehension, although the inner pair can be omitted in this `sum` call. section 7.4.3
Listing 11.15 Retrieving files of the same kind
data_folder = Path("data")
data_files = data_folder.glob("*.dat")
print("Data files:", data_files) #1
for data_file in data_files:
print(f"Processing file: {data_file}")
# applicable data processing steps here
# output the following lines:
Data files: <generator object Path.glob at 0x100b5c040> #2
Processing file: data/subject_124.dat
Processing file: data/subject_125.dat
Processing file: data/subject_123.dat
`Path.glob("*.dat")` supplies matching files through a generator that a `for` loop can process. If another pass is needed after exhaustion, call `glob` again; sort the results when processing order matters. section 11.4.2
Prefer a generator expression for a straightforward, one-off sequence and a generator function when producing values needs a loop and explicit state. As practice, write a generator function that yields Fibonacci numbers up to a specified limit. section 7.4.3 section 7.4.5











