‘xxx’ object is not iterable

エラー詳細

Pythonのエラー

意味

xxxはイテラブルじゃないよ = xxxは for ループで回したりできないよ。

原因

listやtupleみたいなコレクションじゃないものをforで回そうとしたり、mapやfilter関数で使おうとしたときに発生する。「イテラブル(iterable)=forで回せるもの」という認識でほぼ問題ない。

たいていはケアレスミスで発生するが、たまにmatplotlibなんかでは結果が一つだけだったら単体で返す、複数あったらListで返すみたいな迷惑なメソッドがあったりして、それをループで回そうとしたせいでこのエラーにでくわすことがある。

あとどーでもいいけど、個人的に昔よくやりがちだったのがこんなの。C++とかの普通のfor分で慣れてしまってるとこうしたくなる。

    li = [1, 2, 3, 4, 5, 6]
    
    # データの個数だけループ回したい
    for i in len(li):
        print(f"index = {i}")
    # 'int' object is not iterable が発生

    # 正しくはこう
    for i in range(len(li)):
        print(f"index = {i}")

あとはこんなのとか。プロパティ的なものかと思いこんで()忘れる。

    dic = {"hoge": 1, "fuga": 2}
    # 辞書のキーだけ列挙したい
    for key in dic.keys:
        print(key)
    # 'builtin_function_or_method' object is not iterableが発生

    # 正しくはこう
    for key in dic.keys():
        print(key)

エラー対処法

たいていは型の勘違いだったり、上記のようなケアレスミスだったりするので直せばいい。

単体かリストかわからないものを、forで回したいならこうする。

    # なんか状況によって返り値が変わる関数
    results = kaerichikatahumei()
    if not hasattr(results, "__iter__"):
        results = [results]
    for result in results:

iterableなオブジェクトというのはかならず__iter__メソッドを持っている(というかそれがiterableの定義)ので、hasattr関数によりにより__iter__メソッドを持ってるか確認することでiterableかどうかの判定ができる。

で、iterableじゃなかったら、要素一つだけのリストにしてあげてからforの処理に回す。単純に場合分けして別々に処理書くよりもこれのほうがわかりやすい。