1.Iterable vs iterator
An iterable is anything iter() can be called on — a list, a string, a generator function's result. An iterator is what iter() returns: an object that remembers a position and produces one value per next() call.
Key features
- Iterable: defines __iter__, returning an iterator — a list, dict, str, set, range
- Iterator: defines __next__, returning one value per call, usually __iter__ too
- iter(an_iterable) produces a fresh iterator each time, never the same object twice
- Every iterator is itself iterable, but not every iterable is an iterator
- A for loop only requires an iterable — it calls iter() on it once, automatically
Telling the two apart on a real object
Command
iter(obj) # works if obj has __iter__ -> obj is an iterable
next(obj) # works if obj has __next__ -> obj is an iteratorIterable has __iter__ and can be asked for an iterator. Iterator has __next__ and produces values one at a time.