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

2024-12-05 08:38:00
admin
原创
165
摘要:问题描述:我正在学习 Python,并尝试将 GitHub 问题转化为可读的形式。使用如何将 JSON 转换为 CSV?的建议,我想出了这个:import json import csv f = open('issues.json') data = json.load(f) f.close() f = o...

问题描述:

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

解决方案 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]


简短答案

在两个索引之间使用冒号 :代替逗号,`abstr[a:b]`

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

长答案

当使用字符串切片符号(常见的序列操作)时,可能会出现 aTypeError被提升的情况,指出索引必须是整数,即使它们显然是整数。

例子

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

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

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

解释

当我们调用 时,我们隐式地将tuple两个整数中的一个传递给切片符号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

现在,至少错误信息是有意义的。

解决方案

我们需要用冒号替换逗号 ,以正确分隔两个整数,而不是将它们解释为:, :`tuple`

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

  • 在错误消息中添加一些信息,以便用户了解出了什么问题

解决方案 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 数据集iterrows 的 Pandas 文档

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

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

解决方案 6:

正如消息所述,当使用除整数以外的任何值来索引字符串时,就会发生此错误。导致此错误的大多数情况可以归纳为以下情况(以及可能的解决方案)。

字典循环

字典上的 for 循环是针对其键而不是其值的 for 循环,因此迭代它以访问值可能会导致此错误。这种情况很常见,尤其是在字典嵌套很深的情况下。

例如,在 OP 的例子中,字典中的值是包含所需键值对的字典列表。因此,要迭代键下的列表issues,请通过访问它data['issues']并循环遍历它。

# the data is structured like this
data = {"issues": [
    {"gravatar_id": "a", "position": 2.0, "number": 263},
    {"gravatar_id": "b", "position": 1.0, "number": 260},
]}

# iterating over `data` would be over `data`'s keys 
# we want to loop over the list under `'issues'` key
for item in data:
    print(item["gravatar_id"], item["position"], item["number"])   # <--- TypeError

# loop over the list under `issues`
for item in data['issues']:
    print(item["gravatar_id"], item["position"], item["number"])   # <--- OK

还有另一个例子可以说明这一点。这里尝试在循环外部字典的同时访问内部字典。如果我们循环dict_items外部字典,我们就可以循环内部字典,因为现在我们可以访问它们了。

data = {
    'o1': {'i1': 'value1', 'i2': 'value2'},
    'o2': {'i1': 'valu11', 'i2': 'valu22'},
    'o3': {'i1': 'val111', 'i2': 'val222'}
}

for item in data:
    for k in data[item]:
        print(item[k])         # <---- TypeError

for i, item in data.items():
    for k in item:
        print(item[k])         # <---- OK

循环结束dict_items

字典中的值是通过其键访问的。但是,当原本只想访问字典中的值,但 for 循环过度使用时,可能会出现此错误。如果.items()在字典上调用,则无需再次通过键访问值/项;只需按原样使用该值即可。

data = {'k1': 'value1', 'k2': 'value2', 'k3': 'value3'}

for k, item in data.items():
    print(item['k1'], item['k2'], item['k3'])      # <---- TypeError


for k, item in data.items():
    print(item)                                    # <---- OK

未反序列化的 json

这种情况通常发生在 JSON 对象尚未转换为 Python 对象但被当作字典使用时。在下面的示例中,是一个 JSON 对象,因此如果您尝试通过 获取下'data'的值,则会显示错误。'key1'`data['key1']`

import json

data = '''
{
    "key1": "value1",
    "key2": "value2"
}
'''

data['key1']               # <---- TypeError: string indices must be integers

j = json.loads(data)
j['key1']                  # <---- OK

当发出 http 请求、API 调用等时,结果通常非常嵌套,如何处理这些数据并不十分明显,但通过简单的调试步骤(例如打印数据的类型、长度等)通常会显示如何处理它。

print(type(data))                # <class 'str'>    <---- check the data type

Python 字典的字符串文字

有时数据不是 JSON 对象,而只是 Python 对象的字符串表示,在这种情况下ast.literal_eval()解析它可能会很有用。如果这些字符串位于列表或 pandas DataFrame 或其他一些集合中,而这些集合中无法清楚地看出它们是字符串,则这种情况尤其常见。

import ast

data = "{'key1': 'value1', 'key2': 'value2'}"

data['key1']                # <---- TypeError: string indices must be integers
j = json.loads(data)        # <---- JSONDecodeError  
j = ast.literal_eval(data)
j['key1']                   # <---- OK

使用索引字符串input()

一个常见的错误是尝试使用用户输入的值来索引字符串。由于input()返回的是字符串,因此必须先将其转换为整数,然后才能用于索引字符串。

lst = 'my string'
index = input()

lst[index]                                  # <---- TypeError
lst[int(index)]                             # <---- OK

列表/元组/pandas Series 等用于索引字符串

另一种情况(此处前两个答案部分涵盖)是使用除整数以外的任何值对字符串进行索引。解决方案是切片字符串或循环遍历索引列表/系列并索引字符串。

s = 'my string'
s[1,3]                         # <--- TypeError
s[[1,3]]                       # <--- TypeError
s[pd.Series([1,3])]            # <--- TypeError

s[1:3]                         # <--- OK
''.join([s[i] for i in [1,3]]) # <--- OK

解决方案 7:

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

解决方案 8:

对我来说,当我尝试获取id每个客户端循环并抛出函数返回的结果时,会出现此错误getClientByPoweruser;忘记此函数返回一个带有successdata键的对象,而不是客户端项目列表,

result = await getClientByPoweruser(poweruser_id, db)
for client in result:
    print(f'client id:{client["id"]}')

这就是我收到错误的原因:

string indices must be integers, not 'str'

为了解决这个问题,我只需循环抛出result['data']真正包含客户端列表的数组:

for client in result['data']: 
    print(f'client id:{client["id"]}')

#results
#client id:1
#client id:2

解决方案 9:

如果缺少逗号,就会发生这种情况。当我有一个二元组列表时,我遇到了这种情况,每个元组的第一个位置都是一个字符串,第二个位置是一个列表。在一个案例中,我错误地省略了元组第一个组件后的逗号,解释器认为我试图索引第一个组件。

解决方案 10:

将小写字母转换为大写字母:

str1 = "Hello How are U"

new_str = " "

for i in str1:

        if str1[i].islower():

            new_str = new_str + str1[i].upper()

print(new_str)

错误 :

类型错误:字符串索引必须是整数

解决方案 :

for i in range(0, len(str1))
// Use range while iterating the string.
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1590  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1361  
  信创产品在政府采购中的占比分析随着信息技术的飞速发展以及国家对信息安全重视程度的不断提高,信创产业应运而生并迅速崛起。信创,即信息技术应用创新,旨在实现信息技术领域的自主可控,减少对国外技术的依赖,保障国家信息安全。政府采购作为推动信创产业发展的重要力量,其对信创产品的采购占比情况备受关注。这不仅关系到信创产业的发展前...
信创和国产化的区别   18  
  信创,即信息技术应用创新产业,旨在实现信息技术领域的自主可控,摆脱对国外技术的依赖。近年来,国货国用信创发展势头迅猛,在诸多领域取得了显著成果。这一发展趋势对科技创新产生了深远的推动作用,不仅提升了我国在信息技术领域的自主创新能力,还为经济社会的数字化转型提供了坚实支撑。信创推动核心技术突破信创产业的发展促使企业和科研...
信创工作   18  
  信创技术,即信息技术应用创新产业,旨在实现信息技术领域的自主可控与安全可靠。近年来,信创技术发展迅猛,对中小企业产生了深远的影响,带来了诸多不可忽视的价值。在数字化转型的浪潮中,中小企业面临着激烈的市场竞争和复杂多变的环境,信创技术的出现为它们提供了新的发展机遇和支撑。信创技术对中小企业的影响技术架构变革信创技术促使中...
信创国产化   19  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用