閉じる

【Python】TypeError: ‘NoneType’ object is not iterableの原因と直し方

Pythonでデータを繰り返し処理していると、TypeError: ‘NoneType’ object is not iterableに出会うことがよくあります。

これはNoneをリストやタプルのように反復可能(iterable)だと誤解して扱ったときに起きるエラーです。

本記事では、初心者の方でも原因を切り分けて直せるように、典型例と修正パターンを具体的なコード付きで丁寧に解説します。

PythonのTypeError: ‘NoneType’ object is not iterableの意味

意味(Noneを反復処理しようとして失敗)

このエラーは「None(型名はNoneType)は反復可能ではないのに、反復しようとした」ことを示します。

Pythonで反復できるのは、リストやタプル、文字列、辞書、集合、ジェネレータなどのiterableです。

一方Noneは値の欠如を表す特別なオブジェクトであり、反復もアンパックもできません。

なお、場面によってメッセージが少し異なることがあります。

  • forや内包表記での反復 → TypeError: 'NoneType' object is not iterable
  • アンパックでの失敗 → TypeError: cannot unpack non-iterable NoneType object
  • in演算子での判定 → TypeError: argument of type 'NoneType' is not iterable

いずれも根本原因は同じで「Noneをiterableとして扱った」ことです。

発生箇所の典型(for文/リスト内包/アンパック/in演算子)

for文での反復

Python では for 文で対象を反復可能オブジェクト(リスト、タプル、文字列など)とする必要があります。

None は反復可能ではないため、TypeError: 'NoneType' object is not iterable が発生します。

Python
# 反復対象がNone
items = None

for x in items:  # ここでTypeError
    print(x)
実行結果
Traceback (most recent call last):
  File "example.py", line 5, in <module>
    for x in items:
TypeError: 'NoneType' object is not iterable

修正としては、or [] を使ってフォールバックさせるのが簡単です。空リストであれば安全にスキップできます。

Python
items = None

# フォールバックで空リストにする
for x in items or []:
    print(x)
実行結果
# 何も出力されません(安全にスキップ)

リスト内包表記

内包表記も for と同じく、反復可能オブジェクトを期待します。

None を与えるとエラーになるため、やはり or [] で代替するのが定番です。

Python
maybe_none = None
squares = [x * x for x in maybe_none]  # TypeError

以下はor []を使って修正したコードです。

Python
maybe_none = None
squares = [x * x for x in (maybe_none or [])]
print(squares)
実行結果
[]

アンパック

Python のアンパック(a, b = something)では、右辺が必ず反復可能であることが前提です。

None を返す関数をアンパックすると cannot unpack non-iterable NoneType object というエラーになります。

Python
def returns_none():
    # returnしない関数はNoneを返す
    pass

a, b = returns_none()  # cannot unpack non-iterable NoneType object

もし複数の値を返すことを期待するなら、必ずタプルやリストを返すよう関数を実装する必要があります。

Python
def returns_pair():
    return (1, 2)

a, b = returns_pair()
print(a, b)
実行結果
1 2

in演算子

in 演算子も同様に右辺に「反復可能オブジェクト」を必要とします。

None を与えると TypeError: argument of type 'NoneType' is not iterable が出ます。

Python
needle = 1
haystack = None
print(needle in haystack)  # TypeError: argument of type 'NoneType' is not iterable

フォールバックとして (haystack or []) を使えば、存在確認の結果は False に落ち着き、安全です。

Python
needle = 1
haystack = None
print(needle in (haystack or []))  # Falseになる
実行結果
False

NoneTypeが頻発する原因(よくあるケース)

returnし忘れで関数がNoneを返す

Pythonの関数は、returnを書かなかった場合、自動的にNoneを返す仕様です。

そのため、呼び出し側で「リストが返ってくるはず」と思って処理するとエラーになります。

よくあるコード

Python
def even_numbers(nums):
    res = []
    for n in nums:
        if n % 2 == 0:
            res.append(n)
    print("偶数:", res)  # ここで出力して終了(戻り値なし → None)

for x in even_numbers([1, 2, 3, 4]):  # Noneを反復しようとしてTypeError
    print(x)
実行結果
偶数: [2, 4]
Traceback (most recent call last):
  File "example.py", line 8, in <module>
    for x in even_numbers([1, 2, 3, 4]):
TypeError: 'NoneType' object is not iterable

修正例(returnを忘れない)

print()で出力して終わるのではなく、関数は値をreturnして次の処理に渡しましょう。

Python
def even_numbers(nums):
    res = []
    for n in nums:
        if n % 2 == 0:
            res.append(n)
    print("偶数:", res)
    return res  # 結果を返す

for x in even_numbers([1, 2, 3, 4]):
    print(x)
実行結果
2
4

printで終わらせず、値を返すのが基本です。

list.append()の代入でNoneになる

append()リストを直接変更するメソッドで、戻り値は常にNoneです。

代入すると、リストが消えてNoneで上書きされてしまいます。

よくあるコード

Python
nums = [1, 2]
nums = nums.append(3)  # appendは戻り値None。numsがNoneで上書きされる
for n in nums:  # ここでTypeError
    print(n)
実行結果
Traceback (most recent call last):
  File "example.py", line 4, in <module>
    for n in nums:
TypeError: 'NoneType' object is not iterable

修正例(代入しない)

appendsortのように「その場でリストを書き換えるメソッド」は、代入せずに呼び出すだけにします。

Python
nums = [1, 2]
nums.append(3)  # 代入しない(リストを破壊的に変更)
for n in nums:
    print(n)
実行結果
1
2
3

in-placeで変更するメソッドは戻り値Noneという規則を覚えると防げます。

list.sort()の代入でNoneになる

sort()append()と同じく破壊的メソッドなので戻り値はNoneです。

よくあるコード

Python
data = [3, 1, 2]
data = data.sort()  # sortは戻り値None
print(data)         # None
for x in data:      # TypeError
    print(x)

修正例(2通り)

使い分けの目安
  • sorted(list) → 並び替えた新しいリストが欲しいとき
  • list.sort() → 今あるリストを並べ替えたいとき

Python
# 1) 破壊的に並び替える
data = [3, 1, 2]
data.sort()  # 代入しない
print(data)

# 2) 新しい並び替え済みリストを受け取る
data2 = sorted([3, 1, 2])  # こちらは新しいリストを返す
print(data2)
実行結果
[1, 2, 3]
[1, 2, 3]

dict.get(key)がNoneを返す(デフォルト未指定)

辞書のgetメソッドは、キーが存在しないときデフォルトでNoneを返す仕様です。

そのままループや処理に使うとエラーになります。

よくあるコード

Python
conf = {"paths": ["a.txt", "b.txt"]}
for p in conf.get("extra_paths"):  # extra_pathsが無く、Noneを反復しようとしてTypeError
    print(p)

修正例(デフォルトを指定)

見つからなかった場合の代替値を指定しておきましょう。

よく使うのは空リスト[]や空文字""です。

Python
conf = {"paths": ["a.txt", "b.txt"]}
for p in conf.get("extra_paths", []):  # 見つからないときは空リスト
    print(p)
実行結果
# 何も出力されません

re.search()/match()が見つからずNoneになる

正規表現でマッチしなかった場合はNoneが返ります。

これをそのままループやgroup()に渡すとエラーになります。

よくあるコード

Python
import re

m = re.search(r"\d+", "abc")  # 数字が無いのでNone
for part in m:  # TypeError: Noneは反復不可
    print(part)

修正例(存在チェックをしてから使う)

if m is not None: のようにチェックしてから使いましょう。

Python
import re

m = re.search(r"\d+", "abc")
if m is not None:
    print("見つかった:", m.group(0))
else:
    print("見つからなかったのでスキップ")
実行結果
見つからなかったのでスキップ

DBのfetchone()が結果なしでNone

SQLの検索でヒットがなければfetchone()Noneを返します。

そのままループするとエラーです。

最小例(SQLiteで再現)

Python
import sqlite3

con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("create table users(id integer, name text)")
# 挿入なし

row = cur.fetchone()  # 結果がないのでNone
for col in row:       # TypeError
    print(col)

修正例(ガード節で分岐)

if row is None: で分岐して、「データなし」と「データあり」をしっかり分けて処理しましょう。

Python
import sqlite3

con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("create table users(id integer, name text)")
# 挿入なし

row = cur.fetchone()
if row is None:
    print("該当行なし")
else:
    for col in row:
        print(col)
実行結果
該当行なし

またはアンパック時は次のように守ります。

Python
row = cur.fetchone()
if row is None:
    raise ValueError("ユーザーが見つかりません")
user_id, name = row  # ここに到達する時点でNoneではない

json.loads(“null”)がNoneを返す

JSONのnullはPythonのNoneに変換されます。

そのまま反復処理しようとするとエラーです。

よくあるコード

Python
import json

data = json.loads("null")  # PythonではNone
for x in data:             # TypeError
    print(x)

修正例(フォールバック)

(data or []) のように「もしNoneなら空リスト」というフォールバックを書くと安心です。

Python
import json

data = json.loads("null")
for x in (data or []):
    print(x)
実行結果
# 何も出力されません

for x in maybe_noneで迭代対象がNone

「リストかもしれないけど、来ないときはNoneかも」という値をそのままループするとエラーです。

よくあるコード

Python
def iter_items(maybe_iterable):
    for x in maybe_iterable:  # maybe_iterableがNoneだとTypeError
        print(x)

iter_items(None)

修正例(入口で正規化)

(maybe_iterable or []) のように書くと、Noneの場合は空リストになり安全です。

Python
def iter_items(maybe_iterable):
    for x in (maybe_iterable or []):  # Noneなら空にする
        print(x)

iter_items(None)
iter_items([1, 2])
実行結果
1
2

if判定の勘違い(Noneと空リストは別物)

Noneと空リスト([])は意味が違います

どちらもbool()はFalseですが、「値がない(None)」と「要素が0件」は区別すべき場面が多いです。

Python
def process(xs):
    # 悪い例: Noneも[]も同列に扱ってしまう
    if not xs:
        print("スキップ")
        return
    for x in xs:
        print("処理:", x)

process(None)  # 本当にスキップで良いか?
process([])    # この場合は「やることが無い」だけかもしれない

期待が違うなら、意図を明確にしましょう。

Python
def process(xs):
    if xs is None:
        raise ValueError("xsはNoneです")  # 入力不備はエラーに
    for x in xs:  # []なら何も処理しないで無事に終了
        print("処理:", x)

process([])      # 安全に何もせず終了
実行結果
# process([])は出力なしで終了。process(None)はValueErrorを送出する設計

TypeError(NoneType is not iterable)の直し方

基本方針は「Noneをiterableとして扱わない」ことです。

直し方の代表パターンを順に示します。

Noneチェックを追加する(if x is None: …)

一番シンプルな方法です。

「もし値が None なら、処理をスキップしてしまおう」という考え方です。

Python
def use_items(items):
    if items is None:
        print("itemsがNoneのため処理をスキップ")
        return
    for x in items:
        print(x)

use_items(None)
use_items([1, 2])
実行結果
itemsがNoneのため処理をスキップ
1
2

判定は==ではなくisを使うのがPythonでは一般的です。

空のiterableを使う(x or []でフォールバック)

「None のときは空のリストにして、そのまま処理を続ける」方法です。

“None のときに何もせず進めてもOK” という場面に向いています。

Python
def safe_iter(maybe_items):
    for x in (maybe_items or []):
        print(x)

safe_iter(None)
safe_iter(("a", "b"))
実行結果
a
b

このやり方は「Noneなら空に置き換えて続行して問題ない」ときに有効です。

dict.get()にデフォルト値を渡す(dict.get(k, []))

設定やオプションをまとめた dict から値を取り出すときによく使う方法です。

Python
opts = {"include": ["a", "b"]}
includes = opts.get("include", [])
excludes = opts.get("exclude", [])  # 無ければ空リスト
for name in includes + excludes:
    print(name)
実行結果
a
b

.get(key, デフォルト値) を使うと「キーがなければデフォルトを返す」ので便利です。

関数は必ず値をreturnする(printだけで終えない)

関数を作るときに print だけで終わらせると、呼び出し側には None が返ってしまいます。

それを次の処理で繰り返しに使おうとすると、このエラーになります。

Python
def calc_sum(nums):
    total = sum(nums)
    return total  # printで終わらせない

print(calc_sum([1, 2, 3]))
実行結果
6

「処理した結果を次で使う」設計ではreturnが必須です。

代入しないメソッドは代入しない(append/sort)

リストのメソッドの中には「元のリストを直接変える」だけで、戻り値が None のものがあります。

代表例は appendsort

これを代入すると None が入ってしまい、エラーにつながります。

Python
data = [3, 1, 2]
data.append(4)  # 代入しない
data.sort()     # 代入しない
print(data)

# 新しいリストが欲しい場合はsortedを使う
sorted_data = sorted(data)
print(sorted_data)
実行結果
[1, 2, 3, 4]
[1, 2, 3, 4]

「in-place(その場で変更する)か、新しい値を返すか」の違いを覚えておきましょう。

早期returnでNoneを避ける(ガード節)

「もし None ならすぐに return」してしまえば、その下の処理は常に安全に書けます。

これを ガード節 と呼びます。

Python
def normalize(items):
    if items is None:  # ガード節
        return []
    # 以下はitemsがiterableである前提でシンプルに書ける
    return [str(x).strip() for x in items]

print(normalize(None))
print(normalize([" a ", " b "]))
実行結果
[]
['a', 'b']

ガード節により下流のコードが安全で読みやすくなります。

期待しないNoneは明示的にエラーにする(ValueErrorなど)

「ここで None が来るのはおかしい!」という場合は、あえてエラーを出すのも正解です。

早めに失敗させたほうがバグを見つけやすいです。

Python
def require_items(items):
    if items is None:
        raise ValueError("itemsがNoneです。呼び出し側のバグの可能性があります。")
    for x in items:
        print(x)

try:
    require_items(None)
except ValueError as e:
    print("捕捉:", e)
実行結果
捕捉: itemsがNoneです。呼び出し側のバグの可能性があります。

「沈黙して進む」より「早めに失敗させて原因を浮き彫りにする」ほうがデバッグしやすいことが多いです。

初心者向けデバッグ手順(原因の切り分け)

Tracebackで発生行を確認する

まずはエラーメッセージの最下部にある最後のスタックフレームを確認します。

そこに「どのファイルの何行目で、どのコードが失敗したか」が載っています。

text
Traceback (most recent call last):
  File "app.py", line 42, in <module>
    for x in result:
TypeError: 'NoneType' object is not iterable

この例ではapp.pyの42行目for x in result:が原因です。

その行の変数がNoneかprintで確かめる

本当にNoneなのかを確認します。

Python
print("DEBUG result:", result)   # 値の中身
print("DEBUG type:", type(result))  # 型
for x in result:  # ここで落ちるならresultがNoneの可能性が高い
    ...
実行結果
DEBUG result: None
DEBUG type: <class 'NoneType'>

戻り値を分解して確認(type()とis None)

関数の戻り値がNoneになっていないかを確認します。

Python
def get_items():
    # どんな場合にNoneになり得るかを洗い出す
    return None

items = get_items()
if items is None:
    print("itemsがNone。get_itemsのロジックを見直す。")
実行結果
itemsがNone。get_itemsのロジックを見直す。

最小の再現コードを作って原因を特定する

大きなコードのままでは原因が埋もれます。

10〜20行程度の最小ケースに切り詰めましょう。

Python
# 最小再現: 内包表記でNoneを反復
def supplier(flag):
    if flag:
        return [1, 2]
    # flagがFalseのときNoneを返してしまう
    # return [] などに修正すべき

nums = [x for x in (supplier(False))]  # ここでTypeError

この段階でsupplier(False)がNoneを返すことが明らかになり、修正方針が立ちます。

早見表: よくあるNone発生と修正パターン

以下は典型パターンの整理です。

普段のレビューや自己チェックにお使いください。

パターン何が起きるか修正指針
return忘れ関数内でprintのみ呼び出し側でNoneを反復値をreturnする
破壊的メソッドの代入lst = lst.append(x)lstがNoneに上書き代入しない or sorted等を使う
dict.getの未指定d.get("k")None反復d.get("k", [])
正規表現未一致re.search(...)None反復if m is not None
DB結果なしfetchone()None反復/アンパック失敗Noneチェック or 例外送出
JSONのnulljson.loads("null")None反復or []でフォールバック
in演算子x in maybe_noneargument of typeエラーx in (maybe_none or [])

迷ったら「is Noneで明示的に判定」「or []で安全に反復」「破壊的メソッドに代入しない」の3点をまず試してください。

まとめ

TypeError: ‘NoneType’ object is not iterableは、Noneをiterableとして扱ったとき必ず発生する、典型的かつ避けやすいエラーです。

実務では次のポイントを徹底することで多くのトラブルを未然に防げます。

  • 関数は必ず意図した値をreturnする。printで終わらせない
  • appendsortなど破壊的メソッドは代入しない
  • dict.get(key, default)でNoneを回避する。
  • 反復前にis Noneでチェック、問題なければx or []でフォールバック。
  • 「Noneは入力不備」とみなす設計ならValueError等をraiseして早めに失敗させる。

最後に、エラーに遭遇したらTracebackで行番号を特定→該当変数の値と型を確認→最小再現コードで原因を切り分けという流れを習慣化してください。

これだけで『NoneTypeはイテラブルではない』地獄から抜け出せます。

この記事を書いた人
エーテリア編集部
エーテリア編集部

人気のPythonを初めて学ぶ方向けに、文法の基本から小さな自動化まで、実際に手を動かして理解できる記事を書いています。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!