为什么我看到“TypeError:字符串索引必须是整数”?

时间:2011-05-20 21:15:17

标签: python json github

我正在玩学习python并尝试将github问题变成可读形式。使用How can I convert JSON to 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...

7 个答案:

答案 0 :(得分:119)

变量item是一个字符串。索引如下所示:

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

上面的示例使用字符串的0索引来引用第一个字符。

字符串不能有字符串索引(如字典可以)。所以这不起作用:

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

答案 1 :(得分:74)

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

答案 2 :(得分:33)

datadict个对象。所以,像这样迭代它:

Python 2

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

Python 3

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

答案 3 :(得分:14)

切片符号str[a:b]的TypeError

tl; dr:在两个索引:之间使用冒号 a代替逗号b中的str[a:b]


使用字符串切片符号common sequence operation)时,可能会出现TypeError的出现,指出索引必须是整数,即使它们显然是整数。

示例

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

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

这个错误可能非常令人沮丧-特别是在学习Python的初期-因为错误消息有点误导人。

说明

我们在调用my_string[0,5]时会隐式地将一个两个整数的元组(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,)定义
  • 在错误消息中添加一些信息,以使用户了解出了什么问题

欢呼和快乐的编程
温克勒尔


[我知道这个问题已经回答了,这也不是线程启动程序问的确切问题,但是我来到这里是因为上述问题导致了相同的错误消息。至少我花了很多时间才找到那个小错字。

所以我希望这会帮助那些偶然发现相同错误的人,并节省他们发现小错误的时间。]

答案 4 :(得分:0)

如果缺少共同点,就会发生这种情况。当我有一个包含两个元组的列表时,我遇到了它,每个元组由第一个位置的字符串和第二个位置的列表组成。在一个案例中,我错误地在元组的第一个组件之后省略了逗号,并且解释器认为我试图索引第一个组件。

答案 5 :(得分:0)

我在Pandas上遇到了类似的问题,您需要使用iterrows()函数来遍历Pandas数据集Pandas documentation for iterrows

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

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

答案 6 :(得分:0)

作为一个经验法则,当我在Python中收到此错误时,我将函数签名与函数执行进行比较

例如:

def print_files(file_list, parent_id):
    for file in file_list:
        print(title: %s, id: %s' % (file['title'], file['id']

因此,如果我使用错误顺序的参数调用此函数,并将列表作为第二个参数传递,并将字符串作为第一个参数传递:

print_files(parent_id, list_of_files) # <----- Accidentally switching arguments location

该函数将尝试遍历parent_id字符串而不是file_list,并且它将希望看到索引是指向字符串中特定字符的整数,而不是指向字符串的索引(titleid)。

这将导致TypeError: string indices must be integers错误。

由于动态特性(与Java,C#或Typescript等语言相反),Python不会通知您此语法错误。