Why do I see "TypeError: string indexes must be integer"?

I play with both learning python and trying to get github issues in a readable form. Using advice How to convert JSON to CSV? I came up with the following:

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 this, 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? What are string indexes? I am sure that as soon as I get this job, I will have more problems, but for now I just love to work!

UPDATE: When I configure the for statement simply

 for item in data: print item 

what I get ... "problems" - so I'm doing something more complex. Here is a bit of my 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 looks very strange:

 {u'issues': [{u'body': u'Add missing paging (Older>>) lin... 
+162
json python github
May 20 '11 at 21:15
source share
5 answers

item most likely a string in your code; row indexes are square brackets, for example, gravatar_id . So I checked your data variable first to see what you got there; I think data is a list of strings (or at least a list containing at least one string), while it should be a list of dictionaries.

+89
May 20, '11 at 21:16
source share

The item variable is a string. The index is as follows:

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

The above example uses the 0 string index to refer to the first character.

Strings cannot contain string indexes (for example, dictionaries). So this will not work:

 >>> mystring = 'helloworld' >>> print mystring['stringindex'] TypeError: string indices must be integers 
+132
May 20 '11 at 21:18
source share

data is a dict object. So sort it out like this:

Python 2

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

Python 3

 for key, value in data.items(): print(key, value) 
+36
May 20 '11 at 23:07
source share

Type error to indicate fragment str[a:b]

tl; dr: use a colon : instead of a comma between the two indices a and b in str[a:b]




When working with strings and the notation of a slice ( operation with a regular sequence ), it may happen that a TypeError is raised, indicating that the indices must be integers, even if they are obvious.

Example

 >>> my_string = "hello world" >>> my_string[0,5] TypeError: string indices must be integers 

We explicitly passed two integers for the indices to the slice designation, right? So what is the problem here?

This error can be very unpleasant - especially at the beginning of learning Python - because the error message is a little misleading.

Explanation

We implicitly passed a tuple of two integers (0 and 5) into the slice notation when we called my_string[0,5] , because 0,5 (even without parentheses) evaluates to the same tuple as (0,5) .

A comma is actually enough for Python to evaluate something as a tuple:

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

Decision

We need to replace the comma with a colon : to correctly separate two integers:

 >>> my_string = "hello world" >>> my_string[0:5] 'hello' 

A more understandable and useful error message might look something like this:

 TypeError: string indices must be integers (not tuple) 

A good error message shows the user what he did wrong, and it would be more obvious how to solve the problem.

[Therefore, the next time you find yourself responsible for writing a message describing the error, think about this example and add a reason or other useful information to the error message to let you, and possibly other people, understand what went wrong. ]

Lessons learned

  • slice notation uses colons : to separate its indices (and range of steps, for example str[from:to:step] )
  • tuples are defined by commas (for example, t = 1, )
  • add some information to the error messages so that users understand what went wrong

Cheers and happy programming
winklerrr




[I know that this question has already been answered, and it was not the very question that the author of the topic asked, but I came here because of the above problem, which leads to the same error message. At least it took me a while to find this little typo.

Therefore, I hope this helps someone else who stumbles upon the same error and saves them time to detect this tiny error.]

+22
Aug 30 '18 at 13:47
source share

This can happen if the comma is missing. I came across it when I had a list of two tuples, each of which consisted of a line in the first position and a list in the second. In one case, I mistakenly missed the comma after the first component of the tuple, and the interpreter thought that I was trying to index the first component.

0
Apr 24 '17 at 21:40
source share



All Articles