iter()
Turn any iterable into an iterator you can advance with next() — or wrap a callable in a stop-at-sentinel loop.
Common call
it = iter(items)
Returns
an iterator — call next(it) to advance
Replaces
the internal __iter__() call that a for-loop makes
Watch out
iterators are ONE-SHOT — once exhausted, iterating again yields nothing
iter(iterable) / iter(callable, sentinelsentinel — Two-arg form: iteration stops (WITHOUT yielding) when callable() equals this value.type: Any · default: null)
→ iterator
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| iterable | iterable | yes | Single-arg form: any object with __iter__() (list, tuple, dict, str, generator, ...). |
| callable | callable | no | Two-arg form: a callable of zero args. Called repeatedly to produce items. |
| sentinel | Any | no | Two-arg form: iteration stops (WITHOUT yielding) when callable() equals this value. |
Return value
iterator — Single-arg: an iterator over the iterable — calls __iter__() on the object. Two-arg: a "call until sentinel" iterator that invokes callable() repeatedly until it returns the sentinel value.
Common patterns
Get an iterator to advance manually
When you want to consume items one at a time with next().
it = iter(items) first = next(it) second = next(it)
Read until a sentinel
The classic use of the two-arg form — reading a stream in chunks until EOF.
with open("data") as f: for chunk in iter(lambda: f.read(4096), ""): process(chunk)
Skip the first N items
Consume N items manually, then let a for-loop handle the rest.
it = iter(items) for _ in range(n): next(it, None) for item in it: ...
Detect an empty iterable
Use next() with a sentinel default to peek.
it = iter(items) sentinel = object() if next(it, sentinel) is sentinel: ... # empty
Examples
1. From a list
it = iter([1, 2, 3])
next(it)
Returns
12. From a string
it = iter("abc")
next(it)
Returns
"a"3. From a dict (keys)
it = iter({"a": 1, "b": 2})
next(it)
Returns
"a"4. Empty iterator
it = iter([])
next(it, "done")
Returns
"done"5. Two-arg sentinel
r = iter(iter([1,2,3]).__next__, 3)
list(r)
Returns
[1, 2] # stops before 36. Exhausted iterator
it = iter([1])
next(it); next(it, "end")
Returns
"end"Pitfalls
1. Iterators are ONE-SHOT
Once exhausted, an iterator yields nothing. Trying to iterate again gives an empty sequence — a common source of "why is my second loop empty?" bugs.
Empty second time
it = iter([1, 2, 3]) list(it) # [1,2,3] list(it) # []
exhausted
Store the source
items = [1, 2, 3] list(items); list(items)
[1,2,3] both times
2. iterable vs iterator confusion
An ITERABLE can produce iterators (list, dict, str). An ITERATOR is the stateful cursor you actually advance. `iter()` converts iterable → iterator. Once you have an iterator, calling iter() on it returns the same iterator (not a fresh one).
Assumed fresh iterator
it = iter([1, 2, 3]) it2 = iter(it) it is it2
True # NOT a fresh iterator
Fresh from source
src = [1, 2, 3] iter(src) is iter(src)
False # each call is fresh
3. Two-arg form: sentinel is EXCLUDED
The sentinel value marks the end — it is NOT yielded. `iter(f, "STOP")` yields values from f() until one equals "STOP", then stops without yielding that value.
Assumed inclusive
r = iter(iter([1,2,3]).__next__, 3) list(r) # excludes 3
[1, 2]
Sentinel is exclusive by design
# to include the sentinel, take one more with next(it, None) after4. Two-arg callable must take NO arguments
The two-arg form calls callable() with no args. If your callable needs args, wrap it in a lambda or partial.
Wrong arity
iter(f.read, "") # if f.read takes an int arg
depends — may raise, may work
Bind the arg
iter(lambda: f.read(4096), "")
chunks until EOF
When to use
Use it
- Manual consumption via repeated next() calls
- Reading a stream until an EOF sentinel — the two-arg form
- Skipping some items before starting a for-loop
- Detecting empty iterables with next(it, sentinel)
Reach for something else
- A simple for-loop already calls iter() implicitly — do not wrap unnecessarily
- Re-iteration is needed → keep the SOURCE, not the iterator
- Peeking ahead → itertools.tee makes independent copies
- Complex stream logic → generators are usually clearer
Notes
Complexity
O(1) to construct; per-item cost depends on the source
Return
An iterator object — stateful
CPython impl
Python/bltinmodule.c :: builtin_iter — calls PyObject_GetIter or wraps callable+sentinel
Memory
O(1) — a small cursor object
Thread-safe
Not safe under concurrent advancement
FAQ
An ITERABLE is any object you can loop over (list, dict, string, set). An ITERATOR is a stateful cursor produced from an iterable, which you advance with next(). Iterables are typically re-iterable; iterators are one-shot.
History
1.5
iter() and the iterator protocol formalized.
2.2
Two-arg (callable, sentinel) form added.
3.0
Iterators became the return type for map, filter, zip, and range.