Part 10 · Going further — chapter 3 of 5 · chapter 48 of 50 · 7 min read

Iterators and Iterable Objects Explained

An iterable is something you can loop over. An iterator is the object that gives you values one at a time during that loop.

This difference is important because it helps you understand:

  • how for loops work
  • why next() works on some objects but not others
  • why some objects get “used up” after you loop through them

A good short way to remember it is:

  • iterable = can be looped over
  • iterator = produces the next value

The sections below show how iter() and next() connect the two, and what for loops do with them behind the scenes.

Quick example #

numbers = [10, 20, 30]
iterator = iter(numbers)

print(next(iterator))  # 10
print(next(iterator))  # 20
print(next(iterator))  # 30

Use iter() to get an iterator from an iterable like a list. Use next() to read one item at a time.

What this page covers #

  • What an iterable is
  • What an iterator is
  • How iter() and next() work
  • How for loops use iterators behind the scenes
  • What StopIteration means

What is an iterable? #

An iterable is an object you can loop over with a for loop.

Common iterable objects include:

  • lists
  • tuples
  • strings
  • dictionaries
  • sets
  • range() objects
  • files opened for reading

Example:

colors = ["red", "green", "blue"]

for color in colors:
    print(color)

Output:

red
green
blue

Here, colors is iterable because Python can go through its values one by one.

You can also pass an iterable to iter() to get an iterator:

colors = ["red", "green", "blue"]
iterator = iter(colors)

print(iterator)

The exact printed result may look different, but iterator is now an iterator object.

If you want a fuller beginner definition, see what is an iterable in Python.

What is an iterator? #

An iterator is an object that gives values one at a time.

It keeps track of where it is. Each time you call next(), it returns the next item.

Example:

numbers = [10, 20, 30]
iterator = iter(numbers)

print(next(iterator))
print(next(iterator))
print(next(iterator))

Output:

10
20
30

After the last value, there is nothing left to return. At that point, Python raises StopIteration.

numbers = [10, 20, 30]
iterator = iter(numbers)

print(next(iterator))
print(next(iterator))
print(next(iterator))
print(next(iterator))  # no more items

This causes:

StopIteration
[10, 20, 30]iter()iteratornext()102030StopIteration
iter() turns the list into an iterator; each next() returns one value until StopIteration.

If you want a short definition page, see what is an iterator in Python.

Iterable vs iterator #

These two terms are related, but they are not the same.

  • An iterable is the object you can loop over
  • An iterator is the object that produces items during the loop

For example:

numbers = [1, 2, 3]

print(hasattr(numbers, "__iter__"))
print(hasattr(numbers, "__next__"))

Output:

True
False

A list is iterable, but it is not usually an iterator.

Now look at an iterator created from that list:

numbers = [1, 2, 3]
iterator = iter(numbers)

print(hasattr(iterator, "__iter__"))
print(hasattr(iterator, "__next__"))

Output:

True
True

This shows that the iterator can both be iterated over and provide the next value.

Also, calling iter() on an iterator usually returns the same iterator:

numbers = [1, 2, 3]
iterator = iter(numbers)

print(iter(iterator) is iterator)

Output:

True

How iter() and next() work #

These two functions are the core of Python’s iteration system.

iter(object) #

iter(object) asks Python for an iterator for that object.

Example:

text = "abc"
iterator = iter(text)

print(next(iterator))
print(next(iterator))
print(next(iterator))

Output:

a
b
c

next(iterator) #

next(iterator) gets the next item from the iterator.

If there are no items left, Python raises StopIteration.

text = "ab"
iterator = iter(text)

print(next(iterator))
print(next(iterator))
print(next(iterator))

This raises StopIteration on the third call.

You can handle that yourself with try and except:

text = "ab"
iterator = iter(text)

try:
    while True:
        print(next(iterator))
except StopIteration:
    print("Iterator is finished")

Output:

a
b
Iterator is finished

If you want to learn more about this exception, see StopIteration exception in Python explained.

How for loops use iterators #

A for loop does this behind the scenes:

  1. Calls iter() on the object
  2. Repeatedly calls next()
  3. Stops when StopIteration is raised

This means code like this:

numbers = [10, 20, 30]

for number in numbers:
    print(number)

works roughly like this:

numbers = [10, 20, 30]
iterator = iter(numbers)

while True:
    try:
        number = next(iterator)
        print(number)
    except StopIteration:
        break

Output for both:

10
20
30

You do not need to write loops this way in normal code. But understanding it makes for loops much easier to understand.

If you want a full beginner guide, see Python for loops explained.

Examples of iterable objects #

Here are some common iterable objects in Python.

Lists and tuples #

items = [1, 2, 3]
for item in items:
    print(item)

values = (4, 5, 6)
for value in values:
    print(value)

Strings #

for letter in "cat":
    print(letter)

Output:

c
a
t

Dictionaries and sets #

A dictionary loops over its keys by default:

person = {"name": "Ava", "age": 25}

for key in person:
    print(key)

A set is also iterable:

numbers = {1, 2, 3}

for number in numbers:
    print(number)

range() objects #

range() is iterable, which is why it works well in loops.

for number in range(3):
    print(number)

Output:

0
1
2

You can learn more on the Python range() function explained.

Files opened for reading #

Files are iterable too. Python can read them one line at a time.

with open("example.txt", "r") as file:
    for line in file:
        print(line.strip())

This is useful because it reads values one at a time instead of loading everything at once.

When iterators are useful #

Iterators are helpful when you want to work with data step by step.

Common uses:

  • Reading values one at a time
  • Working with large data without loading everything at once
  • Building custom classes that support loops
  • Understanding generators more easily

A very common real-world example is a generator. Generators are a special kind of iterator, so learning this topic makes generators in Python explained much easier to understand.

Beginner mistakes to avoid #

Here are some common problems beginners run into.

Using next() on a list instead of on an iterator #

This is wrong:

numbers = [10, 20, 30]
print(next(numbers))

A list is iterable, but it is not an iterator. You need iter() first:

numbers = [10, 20, 30]
iterator = iter(numbers)

print(next(iterator))

Thinking every iterable is already an iterator #

Objects like lists, strings, and tuples are iterable, but they do not usually have __next__() directly.

Check it:

text = "hello"
print(hasattr(text, "__next__"))

Output:

False

Forgetting that iterators get used up #

Once you consume an iterator, it does not automatically restart.

numbers = [1, 2, 3]
iterator = iter(numbers)

for item in iterator:
    print(item)

for item in iterator:
    print(item)  # nothing prints

If you want to loop again, create a new iterator:

numbers = [1, 2, 3]

for item in iter(numbers):
    print(item)

for item in iter(numbers):
    print(item)

Not handling StopIteration when calling next() manually #

If you call next() yourself, you may need to handle the end of the iterator.

numbers = [1, 2]
iterator = iter(numbers)

try:
    print(next(iterator))
    print(next(iterator))
    print(next(iterator))
except StopIteration:
    print("No more items")

Output:

1
2
No more items

Useful checks when debugging #

If you are not sure whether an object is iterable or an iterator, these checks can help:

obj = [1, 2, 3]

print(type(obj))
print(hasattr(obj, "__iter__"))
print(hasattr(obj, "__next__"))

You can also try creating an iterator:

obj = [1, 2, 3]
iterator = iter(obj)

print(type(iterator))
print(next(iterator))

Useful commands:

  • type(obj)
  • iter(obj)
  • next(iterator)
  • hasattr(obj, '__iter__')
  • hasattr(obj, '__next__')

✍️ Try it yourself

Start with the list ["a", "b", "c"]. Use iter() to get an iterator from it, then use next() three times to print each value one at a time.

Show answer
letters = ["a", "b", "c"]
iterator = iter(letters)

print(next(iterator))
print(next(iterator))
print(next(iterator))
# Output:
# a
# b
# c

FAQ #

Is every iterable also an iterator? #

No. Many objects like lists and strings are iterable, but you must call iter() to get an iterator from them.

What happens when an iterator runs out of values? #

Python raises StopIteration. A for loop handles this automatically.

Can I loop over the same iterator twice? #

Usually no. Once an iterator is exhausted, it does not start over unless you create a new one.

Why should beginners learn this? #

It helps you understand for loops, generators, files, and many common Python tools.

See also #

If this topic makes sense now, the best next step is to learn generators. They are one of the most common real-world examples of iterators in Python.

Press Esc to close