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

424 投票
10 回答
2006276 浏览
提问于 2025-04-16 18:03

我正在学习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"])

for item in data:
    csv_file.writerow([item["gravatar_id"], item["position"], item["number"]])

这里的“issues.json”是包含我GitHub问题的JSON文件。当我尝试运行这段代码时,我遇到了以下错误:

TypeError: string indices must be integers

我这里缺少了什么呢?所谓的“字符串索引”指的是什么?

这是我JSON内容的一部分:

{"issues": [{"gravatar_id": "44230311a3dcd684b6c5f81bf2ec9f60", "position": 2.0, "number": 263...

10 个回答

117

切片表示法中的类型错误 str[a:b]


简短回答

str[a:b] 中,两个索引 ab 之间要用冒号 :,而不是逗号 ,

my_string[0,5]  # wrong ❌
my_string[0:5]  # correct ✅

详细回答

在处理字符串切片表示法(这是一种常见的序列操作)时,可能会遇到TypeError错误,提示说索引必须是整数,即使它们看起来确实是整数。

例子

>>> my_string = "Hello, World!"
>>> my_string[0,5]
TypeError: string indices must be integers

我们显然是给切片表示法传了两个整数,对吧?那这里的问题是什么呢?

这个错误可能会让人很沮丧,尤其是在学习Python的初期,因为错误信息有点误导。

解释

当我们调用 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
                                               ^^^^^
                                         (actual type here)

好的错误信息应该直接告诉用户他们做错了什么!有了这样的信息,找到问题的根源并解决它会容易得多——你也就不需要来这里了。

所以下次,当你负责编写错误描述信息时,记得这个例子,给错误信息添加原因(或其他有用的信息)!帮助其他人(或者将来的自己)理解哪里出了问题。

总结经验

  • 切片表示法使用冒号 : 来分隔索引(以及步长范围,比如 str[from:to:step]
  • 元组是用逗号 , 定义的(例如 t = 1,
  • 给错误信息添加一些信息,帮助用户理解哪里出错了
280

变量 item 是一个字符串。索引的样子是这样的:

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

上面的例子使用了字符串的 0 索引来指代第一个字符。

字符串不能像字典那样使用字符串作为索引。所以这样做是行不通的:

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

item 在你的代码中很可能是一个字符串;字符串的索引就是方括号里的内容,比如 gravatar_id。所以我建议你先检查一下你的 data 变量,看看里面到底有什么。我猜 data 是一个字符串的列表(或者至少包含一个字符串的列表),但它应该是一个字典的列表。

撰写回答