Iteration
Iterator vs Iterable
A list is iterable. Each for loop or list() call asks the list for a fresh iterator under the hood, so the same data can be traversed many times.
Source
names = ["Ada", "Grace"]
print(list(names))
print(list(names))Output
['Ada', 'Grace']
['Ada', 'Grace']An iterator is one-pass. Calling iter() returns a position-tracking object; once it has been exhausted, it stays exhausted.
Source
stream = iter(names)
print(list(stream))
print(list(stream))Output
['Ada', 'Grace']
[]Calling iter() on an iterable returns a brand-new iterator each time. Calling iter() on an iterator returns the same object — that is the rule that lets a for loop accept either kind.
Source
first = iter(names)
second = iter(names)
print(first is second)
print(iter(first) is first)Output
False
TrueThe distinction shows up at API boundaries. A function that loops over its argument twice works for an iterable but silently produces wrong answers for an iterator, because the second pass finds the iterator already exhausted. Materialize once at the boundary when both passes matter.
Source
def total_and_count(numbers):
total = sum(numbers)
count = sum(1 for _ in numbers)
return total, count
def values():
yield from [10, 9, 8]
print(total_and_count([10, 9, 8]))
print(total_and_count(values()))
def total_and_count_safe(numbers):
items = list(numbers)
return sum(items), len(items)
print(total_and_count_safe(values()))Output
(27, 3)
(27, 0)
(27, 3)Notes
- An iterable produces an iterator each time
iter()is called on it; an iterator produces values until it is exhausted. iter(iterable)returns a fresh iterator;iter(iterator)returns the same iterator.- Functions that traverse their input more than once must accept an iterable or materialize the input at the boundary.
See also
- related: Iterators
- related: Iterating over Iterables
- related: Generators
Run the complete example
Expected output
['Ada', 'Grace']
['Ada', 'Grace']
['Ada', 'Grace']
[]
False
True
(27, 3)
(27, 0)
(27, 3)
Execution time appears here after you run the example.