Python

requestにlistやdict変数を格納したのに「TypeError: string indices must be integers」になる原因と解決方法

requestにlistやdict変数を格納したのに「TypeError: string indices must be integers」になる原因と解決方法

GCP上でサーバーの設定をせずにプログラムだけを実行できるCloudFuntions

CloudFuntionsではいくつかのプログラム言語を利用できる。
その中のひとつ「Python」を使い、トリガーに「HTTP」を指定した場合、あるエラーに遭遇することがある。

TypeError: string indices must be integers

requestにstringではなく配列(list)や辞書型(dict)を渡すとこのエラーが発生する。

一体何が原因なのか。

そこで今回は、requestにlistやdict変数を格納したのに「TypeError: string indices must be integers」になる原因と解決方法について解説する。

この記事を書いている人


システムエンジニア、AIエンジニアと、IT業界で10年以上働いている中堅。PythonとSQLが得意。最近GCPを色々と習得中。

記事を読むメリット

  • CloudFunctionsのPythonでrequestにlistやdict変数を格納したのに「TypeError: string indices must be integers」になる原因と解決方法がわかる

  • requestにlistやdict変数を格納したのに「TypeError: string indices must be integers」になる現象

    エラーが発生する現象はどのようなものか。

    まず http request に以下の要素を持つjsonを格納してCloudFunctionsのトリガーとする。

    "data":[{"key1":"val11","key2":"val12"},
    {"key1":"val21","key2":"val22"},
    {"key1":"val31","key2":"val32"}]
    


    CloudFunctions側は request.get_json() でrequestのjsonを読み解き、その中に格納した data 要素を呼ぶ。
    そして data の中の配列を順に print() しようとしている。

    request_json = request.get_json()
    json_data = request_json["data"]
    for v in json_data:
       print(v["key1"])
    


    すると以下のエラーが発生する。

    TypeError: string indices must be integers
    



    「TypeError: string indices must be integers」になる原因

    原因はエラーメッセージを見るとわかる。

    TypeError: string indices must be integers なので「string型の添字はint型でないとダメです」と言っている。

    つまり print(v["key1"]) で辞書型変数の中身を表示しようとしたが、Pythonは辞書型(dict)ではなく文字列型として認識しているのでエラーになっている。


    何故文字列として認識しているかというと、 request.get_json() の仕様。
    request.get_json()で読み込まれた各要素は文字列として認識される

    つまりdata要素の中身は

    [{"key1":"val11","key2":"val12"},
    {"key1":"val21","key2":"val22"},
    {"key1":"val31","key2":"val32"}]
    

    という辞書型を複数格納した配列ではなく

    '[{"key1":"val11","key2":"val12"},
    {"key1":"val21","key2":"val22"},
    {"key1":"val31","key2":"val32"}]'
    

    という長い文字列として認識されているので、辞書型のつもりで要素を呼ぶとエラーになってしまう。



    「TypeError: string indices must be integers」の解決方法

    「TypeError: string indices must be integers」の解決方法だが、文字列を配列(list)や辞書型(dict)として認識させればいい

    文字列を配列(list)や辞書型(dict)として認識させるには eval() を使う。

    request_json = request.get_json()
    json_data = eval(request_json["data"])
    for v in json_data:
       print(v["key1"])
    

    こうすることで eval() に指定した文字列を式として評価し直すので、文字列を配列(list)や辞書型(dict)として認識させることができる。


    eval() については過去記事を参考。



    requestにlistやdict変数を格納したのに「TypeError: string indices must be integers」になる原因と解決方法 まとめ

    CloudFunctionsのPythonを利用する際、requestにlistやdict変数を格納したのに「TypeError: string indices must be integers」になる原因は送ったデータが文字列として認識されているから

    解決方法として、取り込んだ文字列に eval() を適用するとlistやdictとして認識してくれる。


    思ったとおりの型として認識してくれてなかったとは・・・
    Pythonの中で完結していればこのようなトラブルは起きないんですけどね
    Pythonの外側からデータを渡す場合は一旦文字列として認識されるので要注意ですね
    http requestの他にもiniファイルからデータを読み込む場合も同じ事が起きるので注意した方がいいです。



    Pythonの外側からデータを渡す方法として、iniファイルを読む方法についても記事があるので、もし気になったら見て欲しい。

    ITipsと同じようなブログを作る方法

    ブログに興味がありますか?

    もしブログに興味がある場合は↓このページ↓を参考にすれば、ITipsと同じ構成でブログを作ることができます

    サーバー、ドメイン、ASPと【ブログに必要なものは全て】このページに書きました。
    同じ構成でブログ作るのはいいけど、記事はマネしないでネ (TДT;)

    ランキング参加中

    にほんブログ村 IT技術ブログへ

    他にもブログやSNSで紹介してくれると励みになります。

    はてブのコメントで酷評されると泣きます(´;ω;`)

    -Python
    -,

    © 2024 ITips