TypeError: 'list' object is not an iterator (tested fix)

TypeError: 'list' object is not an iterator (also for str, dict or tuple) means you called next() on a sequence. Lists can be looped over but aren't iterators. We reproduced it in Python 3.13 and tested the fixes.

1. next() on a list

A list is iterable (a for loop can walk it), but it is not an iterator, so next() refuses it. Wrap it in iter() first:

items = ["a", "b", "c"]
try:
    print(next(items))
except TypeError as e:
    print(type(e).__name__ + ":", e)
it = iter(items)
print(next(it), next(it))

Output:

TypeError: 'list' object is not an iterator
a b

2. Same error for str, dict and tuple

lines = ["header", "row1", "row2"]
for value in (lines, "header\nrow1", {"k": 1}, (1, 2)):
    try:
        next(value)
    except TypeError as e:
        print(type(e).__name__ + ":", e)

Output:

TypeError: 'list' object is not an iterator
TypeError: 'str' object is not an iterator
TypeError: 'dict' object is not an iterator
TypeError: 'tuple' object is not an iterator

3. The common real case: skipping a CSV header

next(reader) works on a csv.reader, but code that first does list(reader) then calls next() on the list breaks:

import csv, io
data = "name,age\nann,31\nbob,42\n"
rows = list(csv.reader(io.StringIO(data)))
try:
    header = next(rows)               # rows is a list now
except TypeError as e:
    print(type(e).__name__ + ":", e)
reader = csv.reader(io.StringIO(data))
header = next(reader)                 # skip header on the reader itself
print(header, list(reader))

Output:

TypeError: 'list' object is not an iterator
['name', 'age'] [['ann', '31'], ['bob', '42']]

Call next() on the reader before turning it into a list, or slice the list with rows[0] and rows[1:].

4. Your own class: __iter__ alone is not enough for next()

class Countdown:
    def __init__(self, n):
        self.n = n
    def __iter__(self):               # iterable, but not an iterator
        return iter(range(self.n, 0, -1))
c = Countdown(3)
print(list(c))
try:
    next(c)
except TypeError as e:
    print(type(e).__name__ + ":", e)
print(next(iter(c)))

Output:

[3, 2, 1]
TypeError: 'Countdown' object is not an iterator
3

A class with only __iter__ works in loops and list(). For next(obj) it also needs __next__, or callers should use next(iter(obj)).

5. Safe first item, and the StopIteration you get next

items = ["a", "b"]
print(next(iter(items), "empty"), next(iter([]), "empty"))
it = iter(items)
print(next(it), next(it), next(it, "done"))
try:
    next(iter([]))
except StopIteration as e:
    print(type(e).__name__, repr(e))

Output:

a empty
a b done
StopIteration StopIteration()

next(iter(x), default) gives the first item or a default for an empty sequence. Without a default an exhausted iterator raises StopIteration.

6. Trap: calling iter() every time restarts

items = ["a", "b", "c"]
print(next(iter(items)), next(iter(items)))   # new iterator each time
it = iter(items)
print(next(it), next(it))                     # same iterator advances
print(iter(it) is it, iter(items) is items)

Output:

a a
a b
True False

next(iter(items)) twice gives the first item twice, because each iter() on a list makes a fresh iterator. Keep one iterator in a variable. An iterator returns itself from iter(); a list does not. Related: object is not iterable and cannot unpack non-iterable object.

Frequently asked questions

How do I fix 'list' object is not an iterator?

Wrap the list with iter() and call next() on that: it = iter(items); next(it).

What is the difference between an iterable and an iterator?

An iterable (list, str, dict) can produce an iterator with iter(). An iterator also has __next__ and remembers its position. next() only accepts iterators.

How do I get the first item or None?

next(iter(items), None) returns the first item, or None when the list is empty.

Written with AI assistance. Measured on 2026-10-22 on Debian with Python 3.13.5: next() on list/str/dict/tuple, csv.reader before and after list(), a class with only __iter__, next() with a default, and repeated iter() calls. Every block was run verbatim and its output pasted unedited. PlainHeaders is our extension; Python is free.