为什么会看到“ 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

Answers:


116

item您的代码中很可能是字符串;字符串索引是方括号中的那些,例如gravatar_id。因此,我首先要检查您的data变量以查看您在那里收到了什么;我猜这data是一个字符串列表(或至少一个包含至少一个字符串的列表),而它应该是字典列表。


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:在两个索引之间和中使用冒号 :而不是逗号abstr[a:b]


使用字符串切片表示法常见的序列操作)时,可能会TypeError引发a 的增加,指出索引必须是整数,即使它们显然是整数。

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

我们显然将两个整数作为索引传递给切片符号,对吗?那么这是什么问题呢?

该错误可能非常令人沮丧-尤其是在学习Python初期-因为错误消息有点误导。

说明

调用时,我们隐式地将两个整数(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

现在,至少,该错误消息有意义。

我们需要用冒号替换逗号 ,,以正确分隔两个整数: :

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

如果缺少逗号,可能会发生这种情况。当我有一个包含两个元组的列表时,我遇到了它,每个列表中的第一个位置包含一个字符串,第二个位置包含一个字符串。在一种情况下,我错误地省略了元组的第一部分之后的逗号,并且解释器认为我正在尝试索引第一部分。


0

我在Pandas上遇到过类似的问题,您需要使用iterrows()函数来遍历Pandas数据集Pandas文档以进行迭代

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

请注意,您需要处理该函数还返回的数据集中的索引。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.