Python › Iterators & the Iterator Protocol

What is the difference between iter(obj) and using obj directly in a for-loop, in terms of what Python calls internally?

Intermediate

Answer

They are equivalent: a for-loop implicitly calls iter(obj) once to obtain an iterator, then calls next() on that iterator repeatedly until StopIteration. Calling iter() explicitly just lets you obtain and hold onto the iterator object yourself, for example to pass it to another function or advance it manually between loop iterations.
nums = [1, 2, 3]

# Implicit (for-loop does this internally)
for n in nums:
    print(n)

# Explicit equivalent
it = iter(nums)
while True:
    try:
        print(next(it))
    except StopIteration:
        break
Real-world example Understanding this equivalence helps when debugging why modifying a list during a for-loop over it produces unexpected skipped elements -- the loop is really advancing a live iterator.

Common follow-ups: Why is mutating a list while iterating over it risky?;What does calling iter() on an already-iterator object do?