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


219

私は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の問題を含む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

ここで何が欠けていますか?「文字列インデックス」はどれですか?これが機能するようになると、さらに多くの問題が発生すると確信していますが、今のところ、これが機能することを望んでいます!

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...

不足しているのは、print repr(data)またはimport pprint; pprint.pprint(data)
John Machin、

回答:


116

itemおそらくコード内の文字列です。文字列のインデックスは、角かっこ内のインデックスです(例:)gravatar_id。そこで、最初にdata変数をチェックして、そこで受け取ったものを確認します。それdataは文字列のリスト(または少なくとも1つの文字列を含むリスト)ですが、辞書のリストである必要があります。


158

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

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

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

文字列は(辞書のように)文字列インデックスを持つことはできません。したがって、これは機能しません:

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

42

dataあるdictオブジェクトが。したがって、次のように繰り返します。

Python 2

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

Python 3

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

36

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

TL; DR:使用コロン :の代わりにコンマを 2つのインデックス間でa且つbstr[a:b]


文字列スライス表記一般的なシーケンス演算)を扱う場合、a TypeErrorが発生し、インデックスが整数である必要があることを示していても、それが整数でなければならないことを指摘する場合があります。

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

インデックスの2つの整数をスライス表記に渡したことは明らかです。では、ここの問題は何ですか?

エラーメッセージは少し誤解を招くので、このエラーは非常にイライラする可能性があります-特にPythonの学習の始めに-。

説明

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

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

>>> 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


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

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


0

これは、コンマがない場合に発生する可能性があります。最初の位置の文字列と2番目の位置のリストで構成される2つのタプルのリストがあると、それに遭遇しました。あるケースでは、タプルの最初のコンポーネントの後のカンマを誤って省略しました。インタープリターは、最初のコンポーネントをインデックス付けしようとしていると考えました。


0

私はパンダと同様の問題を持っていた、あなたはパンダのデータセットを反復処理するiterrows()関数を使用する必要がiterrowsのためのパンダのドキュメント

data = pd.read_csv('foo.csv')
for index,item in data.iterrows():
    print('{} {}'.format(item["gravatar_id"], item["position"]))

関数からも返されるデータセット内のインデックスを処理する必要があることに注意してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.