I'm playing with both learning Python and am trying to get GitHub issues into a readable form. Using the advice on How can I convert JSON to CSV?, I came up with this:
我正在尝试学习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", "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. When I try to run that, I get
其中“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
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:
当我打印数据时,它看起来被非常奇怪地吞噬:
{u'issues': [{u'body': u'Add missing paging (Older>>) lin...
更多回答
What you are missing is print repr(data)
or import pprint; pprint.pprint(data)
您缺少的是print epr(Data)或import pprint;pprint t.pprint(Data)
Try with square braces, (i.e., data = [json.load(f)] )
尝试使用方括号(即data=[json.load(F)])
The variable item
is a string. 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; the string indices are the ones in the square brackets, e.g., gravatar_id
. So I'd first check your data
variable to see what you received there; 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.
Item最有可能是代码中的字符串;字符串索引是方括号中的索引,例如gravtalid。因此,我首先检查您的数据变量,看看您在那里收到了什么;我猜测数据是一个字符串列表(或者至少包含一个字符串的列表),而它应该是一个字典列表。
TypeError for Slice Notation str[a:b]
Short Answer
Use a colon :
instead of a comma ,
in between the two indices a
and b
in str[a:b]
:
在字符串[a:b]中的两个索引a和b之间使用冒号:而不是逗号:
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]
. 0,5
evaluates to the same tuple as (0,5)
does - even without the parentheses. Why though?
当我们调用MY_STRING[0,5]时,我们隐式地将一个包含两个整数的元组传递给切片表示法。0,5的计算结果与(0,5)的计算结果相同--即使没有括号。但为什么呢?
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
:
我们需要用冒号替换逗号:以正确分隔两个整数,而不是将它们解释为元组:
>>> 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, i.e., str[from:to:step]
)
- tuples are defined by commas
,
(i.e., t = 1,
)
- add some information to error messages for users to understand what went wrong
data
is a dict
object. So, iterate over it like this:
数据是DICT对象。所以,像这样迭代:
Python 2
for key, value in data.iteritems():
print key, value
Python 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时遇到了类似的问题,您需要使用Iterrow()函数来迭代访问Pandas数据集Pandas文档中的Iterrow
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字符串,而不是文件列表,它将看到索引是指向字符串中特定字符的整数,而不是字符串(标题或id)的索引。
This will lead to the TypeError: string indices must be integers
error.
这将导致TypeError:字符串索引必须是整数错误。
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#或TypeScrip等语言相反),Python不会通知您此语法错误。
For me I go this error when I tried to get the id
of each clients looping throw the result returned by the function getClientByPoweruser
;
forgetting that this function returns an object with success
and data
keys rather then list of clients item,
对于我来说,当我试图获取每个客户端的ID时,我会出现这个错误,循环抛出由函数getClientByPoweruser返回的结果;忘记了该函数返回的对象具有成功和数据键,而不是客户端的列表项目,
result = await getClientByPoweruser(poweruser_id, db)
for client in result:
print(f'client id:{client["id"]}')
that is why I got the error:
这就是我收到错误的原因:
string indices must be integers, not 'str'
to fix this I had simply to loop throw result['data']
array which really contains the list of clients:
要解决这个问题,我只需循环抛出结果[‘data’]数组,该数组实际上包含客户列表:
for client in result['data']:
print(f'client id:{client["id"]}')
#results
#client id:1
#client id:2
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.
如果缺少逗号,则可能会发生这种情况。当我有一个由两个元组组成的列表时,我遇到了它,每个元组在第一个位置由一个字符串组成,在第二个位置有一个列表。在一种情况下,我错误地省略了元组第一个组件之后的逗号,解释器认为我正在尝试索引第一个组件。
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
Solution :
解决方案:
for i in range(0, len(str1))
// Use range while iterating the string.
更多回答
Worth noting that this is an error that also commonly arises in nested dictionaries when author forgets to properly nest the calling satements eg.item['findX']
instead of dict[item]['findX']
as in the first example you're trying to find the index findX
in the string/key item
.. hope this makes sense
值得注意的是,这是一个错误,当作者忘记正确嵌套调用语句时,通常也会在嵌套词典中出现这种错误。例如,在第一个示例中,您试图在字符串/关键字项中查找索引findX。希望这是有意义的
Try with square braces, (i.e., data = [json.load(f)] ) to store the json entries as dictionaries
尝试使用方括号(即data=[json.load(F)])将json条目存储为字典
It's not clear what you're suggesting as a solution. Try to use proper code wrapping. Also, for i in range(0, len(x))
is typically not the best way to write a for loop
目前还不清楚你建议的解决方案是什么。尽量使用适当的代码包装。此外,for i in range(0,len(X))通常不是编写for循环的最佳方式
我是一名优秀的程序员,十分优秀!