web-dev-qa-db-ja.com

"TypeError:文字列インデックスは整数でなければならない"と表示されるのはなぜですか?

私はpythonを学ぶこととgithubの問題を読みやすい形式にすることの両方で遊んでいます。 JSONをCSVに変換するにはどうすればいいですか? これを思いついたのです。

import json
import csv

f=open('issues.json')
data = json.load(f)
f.close()

f=open("issues.csv","wb+")
csv_file=csv.writer(f)

csv_file.writerow(["gravatar_id","position","number","votes","created_at","comments","body","title","updated_at","html_url","user","labels","state"])

for item in data:
        csv_file.writerow([item["gravatar_id"], item["position"], item["number"], item["votes"], item["created_at"], item["comments"], item["body"], item["title"], item["updated_at"], item["html_url"], item["user"], item["labels"], item["state"]])

"issues.json"は私のgithubのissueを含むjsonファイルです。実行しようとすると、

File "foo.py", line 14, in <module>
csv_file.writerow([item["gravatar_id"], item["position"], item["number"], item["votes"], item["created_at"], item["comments"], item["body"], item["title"], item["updated_at"], item["html_url"], item["user"], item["labels"], item["state"]])

TypeError: string indices must be integers

私はここで何が足りないのですか? 「文字列インデックス」はどれですか。これがうまくいったら、もっと問題があると思いますが、今のところ、これがうまくいくのが大好きです!

UPDATE:forステートメントを単純に微調整すると

for item in data:
    print item

私が得るものは... "問題"です - だから私はもっと基本的な間違ったことをしています。これが私のjsonです。

{"issues":[{"gravatar_id":"44230311a3dcd684b6c5f81bf2ec9f60","position":2.0,"number":263,"votes":0,"created_at":"2010/09/17 16:06:50 -0700","comments":11,"body":"Add missing paging (Older>>) links...

dataを印刷すると、実際にはおかしくなっているようです。

{u'issues': [{u'body': u'Add missing paging (Older>>) lin...
144
Amanda

itemは、おそらくコード内の文字列です。文字列インデックスは角括弧内のもの、例えばgravatar_idです。それで私は最初にあなたがそこに受け取ったものを見るためにあなたのdata変数をチェックするでしょう。 dataは文字列のリスト(少なくとも1つの文字列を含むリスト)であると思いますが、辞書のリストであるべきです。

78
Tamás

変数itemは文字列です。インデックスは次のようになります。

>>> mystring = 'helloworld'
>>> print mystring[0]
'h'

上記の例では、文字列の0インデックスを使用して最初の文字を参照しています。

文字列は(辞書ができるように)文字列インデックスを持つことはできません。だからこれはうまくいきません。

>>> mystring = 'helloworld'
>>> print mystring['stringindex']
TypeError: string indices must be integers
123
bluepnume

datadictオブジェクトです。だから、このようにそれを繰り返します:

Python 2

for key, value in data.iteritems():
    print key, value

Python 3

for key, value in data.items():
    print(key, value)
33
John Machin

スライス表記のTypeError str[a:b]

tl; dr::の2つのインデックスabの間には、カンマではなくコロンstr[a:b]を使用してください。


stringsおよびスライス表記(a の一般的なシーケンス操作 )を扱うとき、TypeErrorが上がることが起こり得ます。明らかにそうであっても、整数でなければなりません。

>>> my_string = "hello world"
>>> my_string[0,5]
TypeError: string indices must be integers

私たちは明らかに2つの整数をスライスの表記法に渡しましたね。それではここで問題は何ですか?

エラーメッセージは少し誤解を招く可能性があるため、このエラーは非常にイライラすることがあります。

説明

my_string[0,5](括弧なしでも)は0,5と同じTupleに評価されるため、(0,5)を呼び出すときに、暗黙的に2つの整数のタプル(0と5)をスライス表記に渡しました。

Pythonが実際に何かをTupleとして評価するには、カンマ,で十分です。

>>> my_variable = 0,
>>> type(my_variable)
<class 'Tuple'>

それで、我々がそこでしたこと、今度ははっきりと:

>>> my_string = "hello world"
>>> my_Tuple = 0, 5
>>> my_string[my_Tuple]
TypeError: string indices must be integers

さて、少なくとも、エラーメッセージは意味があります。

溶液

2つの整数を正しく区切るには、カンマ,コロン:に置き換える必要があります。

>>> my_string = "hello world"
>>> my_string[0:5]
'hello'

より明確でより役立つエラーメッセージは、次のようなものです。

TypeError: string indices must be integers (not Tuple)

良いエラーメッセージは、彼らが何をしたのかを直接ユーザーに示し、そして問題を解決する方法をもっと明白にしているでしょう。

[それであなたが自分自身でエラー記述メッセージを書く責任があると思うときは、この例を考えてエラーメッセージに理由や他の有用な情報を追加してあなたや他の人々が何が悪いのかを理解させてください。

学んだ教訓

  • スライス表記法はコロン:を使用してそのインデックス(およびステップ範囲、例えばstr[from:to:step])を区切ります。
  • タプルはカンマ,で定義されます(例:t = 1,
  • 何が問題だったのかを理解するためにエラーメッセージに情報を追加する

歓声と幸せなプログラミング
winklerrr


[この質問はすでに答えられていて、これはスレッドスターターが尋ねた質問ではありませんでしたが、上記の問題が原因で同じエラーメッセージが表示されるので、ここに来ました。少なくとも、その小さなタイプミスを見つけるのにかなり時間がかかりました。

それで、これが同じエラーに遭遇した他の誰かを助け、その小さな間違いを見つけるのに時間を節約することを願っています。]

14
winklerrr

これはコモンが欠けている場合に起こります。それぞれが最初の位置の文字列と2番目の位置のリストからなる2つ組のリストを持っていたとき、私はそれに遭遇しました。私は誤ってTupleの最初の構成要素の後のコンマを省略することがあり、インタプリタは最初の構成要素をインデックス付けしようとしていると思いました。

0
Jan Galkowski