PythonのTypeError: 'NoneType' object is not iterableを修正する

beginner🐍 Python2026-04-22| Python 3.x(Linux、macOS、Windows)

Error Message

TypeError: 'NoneType' object is not iterable
#python#typeerror#none#イテレーション#デバッグ

エラーの内容

関数の戻り値、データベースの行、APIレスポンスなど、何かをループ処理しようとしたときに、Pythonが次のエラーを投げることがあります:

TypeError: 'NoneType' object is not iterable

つまり、Noneに対してイテレートしようとしたということです。forループ、リスト内包表記、タプルのアンパック、*スプレッドなど、Pythonのすべてのイテレーション機構は実際のイテラブルを必要とします。Noneはイテラブルではありません。

最も簡単な再現方法はこちらです:

def get_users():
    pass  # returnを書き忘れた

for user in get_users():  # ここでTypeError
    print(user)

根本原因

明示的なreturn文を持たないPython関数は、暗黙的にNoneを返します。これは言語仕様であり、バグではありません。ただし、同じ落とし穴を引き起こすパターンが他にもいくつかあります:

  • 考慮していない分岐で関数がNoneを返す場合 — たとえば、対応するelseのないif文など
  • list.sort()dict.update()などのインプレースメソッドはオブジェクトを変更してNoneを返す — 常に
  • ORMクエリ、データベースカーソル、またはAPI呼び出しが、結果セットが空の場合にNoneを返す
  • そういったインプレースメソッドの戻り値を変数に代入してしまう

最後のパターンは開発者が頻繁にはまる罠です。具体的にはこのような形になります:

items = [3, 1, 2]
items = items.sort()  # sort()はソート済みリストではなくNoneを返す!

for item in items:  # TypeError: 'NoneType' object is not iterable
    print(item)

itemsは今やNoneです。元のリストはソートされていますが、その参照を捨ててしまったのです。

修正方法

修正1:関数が実際に何を返すかを確認する

ループの前に、値を出力または確認します:

result = get_users()
print(type(result), result)  # デバッグ:実際に何が得られたか確認

出力が<class 'NoneType'> Noneであれば、関数が期待通りの値を返していません。該当箇所を見つけてreturn文を追加してください:

def get_users():
    users = db.query("SELECT * FROM users")
    return users  # 以前は抜けていた

修正2:明示的なNoneチェックでガードする

Noneが正当な結果となる場合もあります — 結果なし、処理対象なし。イテレートする前にガード処理を入れましょう:

users = get_users()

if users is not None:
    for user in users:
        print(user)

または1行にまとめることもできます:

for user in (users or []):
    print(user)

or []usersNoneのときに空のリストで代替します。ループは0回実行され、例外も発生しません。

修正3:関数内でデフォルトの空コレクションを返す

呼び出し箇所ごとに修正するのは手間がかかります。関数を一度だけ修正しましょう:

def get_users():
    result = db.query("SELECT * FROM users")
    if result is None:
        return []  # 常にリストを返す
    return result

呼び出し元は自由にイテレートできます。各使用箇所でガード処理を書く必要はありません。

修正4:インプレースメソッドの代入の罠を修正する

list.sort()list.reverse()dict.update()set.add()はいずれもインプレースで変更を行い、Noneを返します。その戻り値を代入しないでください:

# 間違い
items = items.sort()

# 正しい:インプレースでソートし、参照を維持する
items.sort()

# または sorted() を使う — 新しいリストを返す
items = sorted(items)

修正5:チェーン呼び出しのNoneを処理する

メソッドチェーンはNoneを隠蔽し、後になって爆発します。これは危険です:

# response.json()がNoneを返す可能性がある
for item in response.json().get("results"):
    process(item)

分解して各ステップで確認してください:

data = response.json()
results = data.get("results") if data else []
for item in (results or []):
    process(item)

修正6:セイウチ演算子(Python 3.8以降)

関数が外部のもので戻り値の型を変更できない場合、セイウチ演算子は2行のチェックよりもすっきりと書けます:

if (users := get_users()) is not None:
    for user in users:
        print(user)

Noneの発生源を探す

トレースバック全体を読んでください。Pythonは正確な行を特定してくれます:

Traceback (most recent call last):
  File "app.py", line 12, in process_orders
    for order in get_orders(user_id):
TypeError: 'NoneType' object is not iterable

12行目に移動してください。イテラブルはget_orders(user_id)です。その上にデバッグ出力を追加します:

result = get_orders(user_id)
print(f"get_orders returned: {result!r}")
for order in result:
    ...

!rフォーマットは値に対してrepr()を呼び出します。None、空文字列''、空リスト[]を明確に区別できます — repr出力ではこれらの3つはすべて異なる表示になります。

動作確認

修正後にコードを再実行してください。TypeErrorが発生しなければ成功です。ガードパスがNoneを正しく処理することを確認するには、明示的にシミュレーションします:

def get_users():
    return None  # 結果なしをシミュレート

users = get_users()
for user in (users or []):
    print(user)

print("Done — no error")

期待される出力:

Done — no error

ループ本体はスキップされます。例外も発生しません。これが望ましい動作です。

予防策

  • 型ヒントを追加するdef get_users() -> list[User]:は期待される戻り値の型を文書化します。mypyを実行すると、Noneを返すコードパスにフラグを立ててくれます。
  • Optionalを正直に使う:関数が正当にNoneを返す可能性がある場合は、Optional[list]とアノテーションしてください。これにより呼び出し元に「イテレートする前に確認してください」というシグナルを送れます。
  • インプレースメソッドの戻り値を代入しないsort()reverse()update()append() — これらはすべてNoneを返します。頭に叩き込んでおきましょう。
  • Noneではなく空のコレクションを返す:リストを取得する関数は、空の結果のときNoneではなく[]を返すべきです。Noneは「この値が存在しない」という意味に留めましょう — 「何も見つからなかった」ではありません。

Related Error Notes