简体   繁体   English

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

[英]Why am I seeing "TypeError: string indices must be integers"?

I'm playing with both learning Python and am trying to get GitHub issues into a readable form.我正在学习 Python 并尝试将 GitHub 问题转换为可读形式。 Using the advice on How can I convert JSON to CSV?使用有关如何将 JSON 转换为 CSV 的建议? , I came up with this: ,我想出了这个:

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

Where "issues.json" is the JSON file containing my GitHub issues.其中“issues.json”是包含我的 GitHub 问题的 JSON 文件。 When I try to run that, I get当我尝试运行它时,我得到

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

What am I missing here?我在这里想念什么? Which are the "string indices"?哪些是“字符串索引”? I'm sure that once I get this working I'll have more issues, but for now, I'd just love for this to work!我敢肯定,一旦我得到这个工作,我会有更多的问题,但现在,我只是喜欢这个工作!

When I tweak the for statement to simply当我将for语句调整为简单

for item in data:
    print item

what I get is... "issues" -- so I'm doing something more basic wrong.我得到的是……“问题”——所以我做错了一些更基本的错误。 Here's a bit of my JSON content:这是我的一些 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...

when I print data , it looks like it is getting munged really oddly:当我打印data时,它看起来真的很奇怪:

{u'issues': [{u'body': u'Add missing paging (Older>>) lin...

The variable item is a string.变量item是一个字符串。 An index looks like this:索引如下所示:

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

The above example uses the 0 index of the string to refer to the first character.上面的示例使用字符串的0索引来引用第一个字符。

Strings can't have string indices (like dictionaries can).字符串不能有字符串索引(就像字典一样)。 So this won't work:所以这行不通:

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

item is most likely a string in your code; item很可能是代码中的字符串; the string indices are the ones in the square brackets, eg, gravatar_id .字符串索引是方括号中的索引,例如gravatar_id So I'd first check your data variable to see what you received there;所以我首先检查你的data变量,看看你在那里收到了什么; I guess that data is a list of strings (or at least a list containing at least one string) while it should be a list of dictionaries.我猜data是一个字符串列表(或者至少是一个包含至少一个字符串的列表),而它应该是一个字典列表。

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


Short Answer简答

Use a colon : instead of a comma , in between the two indices a and b in str[a:b] :str[a:b]的两个索引ab之间使用冒号:而不是逗号,

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

Long Answer长答案

When working with strings and slice notation (a common sequence operation ), it can happen that a TypeError is raised, pointing out that the indices must be integers, even if they obviously are.在使用字符串切片表示法常见的序列操作)时,可能会TypeError ,指出索引必须是整数,即使它们显然是整数。

Example例子

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

We obviously passed two integers for the indices to the slice notation, right?我们显然将两个整数作为索引传递给切片符号,对吧? So what is the problem here?那么这里的问题是什么?

This error can be very frustrating - especially at the beginning of learning Python - because the error message is a little bit misleading.这个错误可能非常令人沮丧——尤其是在开始学习 Python 时——因为错误信息有点误导。

Explanation解释

We implicitly passed a tuple of two integers to the slice notation when we called my_string[0,5] .当我们调用my_string[0,5]时,我们将两个整数的tuple隐式传递给切片表示法。 0,5 evaluates to the same tuple as (0,5) does - even without the parentheses. 0,5计算为与(0,5)相同的元组 - 即使没有括号。 Why though?为什么呢?

A trailing comma , is actually enough for the Python interpreter to evaluate something as a tuple:结尾的逗号,实际上足以让 Python 解释器将某些内容评估为元组:

>>> my_variable = 0,
>>> type(my_variable)
<class 'tuple'>

So what we did there, this time explicitly:所以我们在那里做了什么,这一次是明确的:

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

Now, at least, the error message makes sense.现在,至少,错误信息是有意义的。

Solution解决方案

We need to replace the comma , with a colon : to separate the two integers correctly, not having them interpreted as a tuple :我们需要用冒号替换逗号,以正确分隔两个整数,而不是将它们解释为tuple :

>>> my_string = "Hello, World!"
>>> my_string[0:5]
'hello'

A clearer and more helpful error message could have been something like:更清晰、更有帮助的错误消息可能类似于:

TypeError: string indices must be integers not tuple
                                               ^^^^^
                                         (actual type here)

A good error message should show the user directly what they did wrong!一个好的错误信息应该直接向用户展示他们做错了什么! With this kind of information it would have been much more easier to find the root cause and solve the problem - and you wouldn't have had to come here.有了这种信息,找到根本原因和解决问题会容易得多——而且您不必来这里。

So next time, when you find yourself responsible for writing error description messages, remind yourself of this example and add the reason (or other useful information) to error message!所以下一次,当你发现自己有责任编写错误描述消息时,提醒自己这个例子并将原因(或其他有用的信息)添加到错误消息中! Help other people (or maybe even your future self) to understand what went wrong.帮助其他人(或者甚至是你未来的自己)了解哪里出了问题。

Lessons learned得到教训

  • slice notation uses colons : to separate its indices (and step range, ie, str[from:to:step] )切片表示法使用冒号:来分隔其索引(和步长范围,即str[from:to:step]
  • tuples are defined by commas , (ie, t = 1, )元组由逗号定义, (即t = 1,
  • add some information to error messages for users to understand what went wrong在错误消息中添加一些信息,以便用户了解出了什么问题

data is a dict object. data是一个dict对象。 So, iterate over it like this:所以,像这样迭代它:

Python 2蟒蛇2

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

Python 3蟒蛇 3

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

I had a similar issue with Pandas, you need to use the iterrows() function to iterate through a Pandas dataset Pandas documentation for iterrows我对 Pandas 有类似的问题,您需要使用 iterrows() 函数来遍历 Pandas 数据集Pandas 文档 for iterrows

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

note that you need to handle the index in the dataset that is also returned by the function.请注意,您需要处理函数返回的数据集中的索引。

As a rule of thumb , when I receive this error in Python I compare the function signature with the function execution .根据经验,当我在 Python 中收到此错误时,我会将函数签名与函数执行进行比较

For example:例如:

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

So if I'll call this function with parameters placed in the wrong order and pass the list as the 2nd argument and a string as the 1st argument:因此,如果我将调用此函数并使用以错误顺序放置的参数并将列表作为第二个参数和一个字符串作为第一个参数传递:

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

The function will try to iterate over the parent_id string instead of file_list and it will expect to see the index as an integer pointing to the specific character in string and not an index which is a string ( title or id ).该函数将尝试迭代parent_id字符串而不是file_list ,并且它希望将索引视为指向字符串中特定字符的整数,而不是作为字符串( titleid )的索引。

This will lead to the TypeError: string indices must be integers error.这将导致TypeError: string indices must be integers错误。

Due to its dynamic nature (as opposed to languages like Java, C# or Typescript), Python will not inform you about this syntax error.由于其动态特性(与 Java、C# 或 Typescript 等语言相反),Python 不会通知您此语法错误。

Converting the lower case letters to upper:将小写字母转换为大写:

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)

Error :错误 :

TypeError: string indices must be integers TypeError:字符串索引必须是整数

Solution :解决方案 :

for i in range(0, len(str1))
// Use range while iterating the string.

How to read the first element of this JSON?如何读取这个 JSON 的第一个元素? when the file appears like this当文件看起来像这样

for i in data[1]:
print("Testing"+i['LocalObservationDateTime'])

This is not working for me.这对我不起作用。 Below is the JSON file下面是 JSON 文件

 [ { "LocalObservationDateTime":"2022-09-15T19:05:00+02:00", "EpochTime":1663261500, "WeatherText":"Mostly cloudy", "WeatherIcon":6, "HasPrecipitation":false, "PrecipitationType":"None", "IsDayTime":true, "Temperature":{ "Metric":{ "Value":11.4, "Unit":"C", "UnitType":17 }, "Imperial":{ "Value":52.0, "Unit":"F", "UnitType":18 } }, "RealFeelTemperature":{ "Metric":{ "Value":8.4, "Unit":"C", "UnitType":17, "Phrase":"Chilly" } } }, { "LocalObservationDateTime":"2022-09-16T19:05:00+02:00", "EpochTime":1663261500, "WeatherText":"Mostly cloudy", "WeatherIcon":6, "HasPrecipitation":false, "PrecipitationType":"None", "IsDayTime":true, "Temperature":{ "Metric":{ "Value":11.4, "Unit":"C", "UnitType":17 }, "Imperial":{ "Value":52.0, "Unit":"F", "UnitType":18 } }, "RealFeelTemperature":{ "Metric":{ "Value":8.4, "Unit":"C", "UnitType":17, "Phrase":"Chilly" } } } ]

This can happen if a comma is missing.如果缺少逗号,可能会发生这种情况。 I ran into it when I had a list of two-tuples, each of which consisted of a string in the first position, and a list in the second.当我有一个双元组列表时,我遇到了它,每个元组都由第一个位置的字符串和第二个位置的列表组成。 I erroneously omitted the comma after the first component of a tuple in one case, and the interpreter thought I was trying to index the first component.在一种情况下,我错误地在元组的第一个组件之后省略了逗号,解释器认为我正在尝试索引第一个组件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM