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

Posted

技术标签:

【中文标题】为啥我看到“TypeError:字符串索引必须是整数”?【英文标题】:Why am I seeing "TypeError: string indices must be integers"?为什么我看到“TypeError:字符串索引必须是整数”? 【发布时间】:2011-08-29 23:29:10 【问题描述】:

我正在学习 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...

【问题讨论】:

你缺少的是print repr(data)import pprint; pprint.pprint(data) 尝试使用方括号,(即 data = [json.load(f)] ) 【参考方案1】:

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

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

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

字符串不能有字符串索引(就像字典一样)。所以这行不通:

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

【讨论】:

【参考方案2】:

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

【讨论】:

【参考方案3】:

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


简答

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

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

长答案

当使用 stringsslice notation(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(即使没有括号)的计算结果与 @ 相同的元组987654332@ 可以。

逗号 , 实际上足以让 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】:

data 是一个 dict 对象。所以,像这样迭代它:

Python 2

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

Python 3

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

【讨论】:

【参考方案5】:

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

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

【讨论】:

尝试使用方括号(即 data = [json.load(f)] )将 json 条目存储为字典【参考方案6】:

根据经验,当我在 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 不会通知您此语法错误。

【讨论】:

【参考方案7】:

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

【讨论】:

以上是关于为啥我看到“TypeError:字符串索引必须是整数”?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我看到多个 set-cookie 标头?

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

为啥我没有看到通过 Python 中的多处理加速?

为啥我在分析器中看到 __scalbnf?

为啥我看到 ELB 运行状况检查加倍?

为啥我在调用 ResultSet.refreshRow() 时会看到 NotUpdatable?