for loops work), generators (memory-efficient value producers), and context managers (automatic resource clean-up).
Comprehensions
Comprehensions provide a concise way to build new collections from existing ones.List Comprehensions
Dictionary Comprehensions
Set Comprehensions
Set comprehensions automatically deduplicate results:Iterators
An iterator is an object that produces one value at a time. It must implement two methods:__iter__()— returns the iterator object itself.__next__()— returns the next value; raisesStopIterationwhen exhausted.
for loop calls iter() on the target, then repeatedly calls next() on the resulting iterator until StopIteration is raised.
Generators
Generators are a simpler way to create iterators using theyield keyword. A generator function pauses at each yield, remembers its state, and resumes on the next call — producing one value at a time rather than storing them all in memory.
Generator Functions
Generators for Large Datasets
Generator Expressions
Wrapped in() instead of [], generator expressions compute values lazily — only when requested:
Generators vs. Lists
Context Managers
Context managers manage resources by guaranteeing that set-up and clean-up code always runs, even if an exception occurs.The with Statement
The most familiar context manager opens files safely:
Creating Custom Context Managers
Use the@contextmanager decorator from contextlib for a concise generator-based approach:
yield runs at the start of the with block. Code after yield (or in finally) runs when the block exits — whether normally or due to an exception.