正如该错误信息所述,当使用一个字符串作为列表的索引时,就会出现此错误。大多数导致这种错误的情况可以归纳为以下几种情况。
1. 列表被用作字典
1.1. 把列表当做字典进行索引
这种情况通常发生在将JSON对象转换为Python对象时,但其中有一个嵌套在列表中的字典。如果列表中只有一个字典,则特别麻烦(也容易忽略)。在下面的示例中,'summary'
关键字下的值是包含单个字典的列表。因此,如果尝试使用json['summary']['home_score']
来获取主队得分,则会显示错误。
json = {
"teams": {"home": "BOS", "away": "MIA"},
"summary": [
{"home_score": 0, "away_score": 0}
]
}
json['summary']['home_score']
json['summary'][0]['home_score']
[d['home_score'] for d in json['summary']]
在进行HTTP请求、API调用等操作时,通常会得到非常嵌套的结果,不太明显如何处理这些数据。但是通过简单的调试步骤,例如打印数据的类型、长度等信息,通常可以展示如何处理它们。
print(type(json['summary']))
print(len(json['summary']))
print(type(json['summary'][0]))
1.2. 将值分配给列表,就像它是字典一样
另一个常见的错误是初始化一个列表,但尝试使用键为其分配值。初始化可能是动态的,后来并不清楚它实际上是一个列表。例如,在以下情况下,d
被初始化为一个列表,但尝试向其中添加键值对。解决方案是初始化一个空字典 {}
而不是 []
。
d = []
d['key'] = 1
d = {}
d['key'] = 1
1.3. pandas dataframe被意外地转换为列表
一种常见的更改pandas dataframe列标签的方法是直接将一个字符串列表分配给pd.DataFrame.columns
属性,以成为新标签。如果将其分配给pd.DataFrame
,则整个dataframe将被替换为列表,并且不再能够通过标签访问列。
import pandas as pd
df = pd.DataFrame([range(4), range(4)])
df = ['A', 'B', 'C', 'D']
df['A']
df = pd.DataFrame([range(4), range(4)])
df.columns = ['A', 'B', 'C', 'D']
df['A']
2. 字符串被当作整数使用
2.1. 使用input()
索引列表
一个非常常见的错误是尝试使用用户输入的值来索引列表。因为input()
返回一个字符串,所以在用它来索引列表之前必须将其转换为整数。
lst = ['a', 'b', 'c']
index = input()
lst[index]
lst[int(index)]
2.2. 使用字符串列表索引列表
另一个常见的错误是循环遍历列表并使用列表项来索引列表。Python 的 for
循环类似于 Perl 的 foreach
,因为循环是在一组项目上进行的。由于列表已经被迭代,所以没有必要再次对其进行索引,因此解决方案是直接使用该项进行需要完成的操作。或者循环遍历使用列表长度构造的 range
对象。
lst = ['a', 'b', 'a', 'd']
lst['a']
lst[lst.index('a')]
这个错误很可能在一个动态创建lst
的循环中更频繁地发生。
for i in lst:
if lst[i] == 'b':
pass
for i in lst:
if i == 'b':
pass
for i in range(len(lst)):
if lst[i] == 'b':
pass
注意: 这是 OP 的情况。使用字符串在列表中进行循环使用了字符串索引。解决方法是循环一个范围对象。
array_length
定义为字符串,所以i
是一个字符而不是数字... - jonrsharpe{thisthing}
时,实际上我正在解析[{thisthing}]
,例如,我试图处理一个字典,但实际上我正在处理一个列表。动态类型很棒。 - Tommy