Python学習チャンネル by PyQ

Pythonのオンライン学習プラットフォームPyQのオフィシャルブログです

PythonのTypeError: list indices must be integers or slices, not strは何ですか?

f:id:nana_yu:20180502143157p:plain

f:id:nana_yu:20180316122251j:plain
清原 こんにちは。PyQ開発チームの清原 id:hirokiky です。

プログラミングをする中で一番大変で、時間がかかるのはデバッグしている時間ではないかと思います。

Pythonにもいくつかエラーがありますが TypeError 、とくに TypeError: list indices must be integers or slices, not str について解説します。 PyQのメールサポートでいただいた質問から、一部を抜粋して解説します。 (質問をくれた方には掲載の許可をいただいています)

質問

book_user = []
with open("input/room.csv", encoding="utf-8") as f:
    for row in f:
        columns = row.rstrip().split(",")
        name = columns[1]
        
        if name in book_user:
            book_user[name] += 1
        else:
            book_user[name] = 1

自分なりにコードを書いてみたんですけど、うまくいきません。 同じ名前を追加しないようにするには、どうしたらいいのかわからないんですが…

回答

これは book_user に、重複しないように name を入れる処理ですね。

まず、エラーの内容について解説します。

TypeErrorの内容

TypeError: list indices must be integers or slices, not str.

TypeErrorというエラーは「型(文字列、数字、リストや辞書)の種類が違いませんか?」というエラーです。

エラーの内容は「リストに [] するときは文字列は使えませんよ。数字かスライス ([3:8]のようなもの)にしてください」ということです。

ここで book_user はリストで、 name はファイルから読み込んできた文字列なのでTypeErrorになります。

変更するなら

上記のプログラムであれば、以下のように書き換えられそうです。

book_user = []
with open("input/room.csv", encoding="utf-8") as f:
    for row in f:
        columns = row.rstrip().split(",")
        name = columns[1]
        
        if name not in book_user:
            book_user.append(name)

これで、 book_user にユニークな name を追加する処理ができます。

もしくは、 book_user に集合を使っても良いですね。 こちらの方が辞書を使っているので動作は速くなります。

book_user = set()
with open("input/room.csv", encoding="utf-8") as f:
    for row in f:
        columns = row.rstrip().split(",")
        name = columns[1]
        
        book_user.add(name)

おわりに

エラーの内容を見て、読んでプログラムを修正するのもプログラミングに必要なスキルです。 PyQではプログラミングを学ぶとき、エラーを実際の環境と同じように表示してくれるので、エラーの読み解き方の勉強にもなります。 ぜひ、エラーを味方につけるプログラマーになりましょう。

Copyright ©2017- BeProud Inc. All rights reserved.