Reading a JSON string | TypeError: string indices must be integers
Solution 1
You are never parsing the string to a dictionary (json object). Change data = mtext
to: data = json.loads(mtext)
You should also add global data
to the readText method
Solution 2
TypeError: string indices must be integers
means an attempt to access a location within a string using an index that is not an integer. In this case your code (line 18) is using the string "type"
as an index. As this is not an integer, a TypeError
exception is raised.
It seems that your code is expecting data
to be a dictionary. There are (at least) 3 problems:
- You are not decoding ("loading") the JSON string. For this you should use
json.loads(data)
in thereadText()
function. This will return the dictionary that your code expects elsewhere. data
is a global variable with value initialised to an empty string (""
). You can not modify a global variable within a function without first declaring the variable using theglobal
keyword.- The code builds a list by appending successive items to it, however, that list is not used elsewhere. It is printed after the definition of
_getCurrentOperator()
but this is before any processing has been done, hence it is still empty at that point and[]
is displayed. Moveprint(list)
tomhello()
after_getCurrentOperator()
. (BTW usinglist
as a variable name is not advised as this shadows the builtinlist
)
You can revise readText()
to this:
def readText():
global data
mtext=""
mtext = strJson.get()
mlabel2 = Label(myGui,text=mtext).place(x=180,y=200)
data = json.loads(mtext)
Solution 3
sometimes you need to use json.loads again.. this worked for me..
jsonn_forSaleSummary_string = json.loads(forSaleSummary) //still string
jsonn_forSaleSummary = json.loads(jsonn_forSaleSummary_string)
finally!! json
Billy Dawson
Updated on November 27, 2020Comments
-
Billy Dawson over 3 years
I'm trying to create a program that will read in a JSON string through the GUI and then use this to perform additional functions, in this case breaking down a mathematical equation. At the moment I am getting the error:
"TypeError: string indices must be integers"
and I have no idea why.
The JSON I am trying to read in is as follows:
{ "rightArgument":{ "cell":"C18", "value":9.5, "type":"cell" }, "leftArgument":{ "rightArgument":{ "cell":"C3", "value":135, "type":"cell" }, "leftArgument":{ "rightArgument":{ "cell":"C4", "value":125, "type":"cell" }, "leftArgument":{ "cell":"C5", "value":106, "type":"cell" }, "type":"operation", "operator":"*" }, "type":"operation", "operator":"+" }, "type":"operation", "operator":"+" }
import json import tkinter from tkinter import * data = "" list = [] def readText(): mtext="" mtext = strJson.get() mlabel2 = Label(myGui,text=mtext).place(x=180,y=200) data = mtext def mhello(): _getCurrentOperator(data) def _getCurrentOperator(data): if data["type"] == "operation": _getCurrentOperator(data["rightArgument"]) _getCurrentOperator(data["leftArgument"]) list.append(data["operator"]) elif data["type"] == "group": _getCurrentOperator(data["argument"]) elif data["type"] == "function": list.append(data["name"]) # TODO do something with arguments for i in range(len(data["arguments"])): _getCurrentOperator(data["arguments"][i]) else: if (data["value"]) == '': list.append(data["cell"]) else: list.append(data["value"]) print(list) myGui = Tk() strJson = StringVar() myGui.title("Simple Gui") myGui.geometry("400x300") label = Label(text = 'Welcome!').place(x=170,y=40) btnStart = Button(myGui,text='Start',command=mhello).place(x=210,y=260) btnRead = Button(myGui,text='Read text',command=readText).place(x=210,y=200) txtEntry = Entry(myGui, textvariable=strJson).place(x=150,y=160) btnOptions = Button(myGui, text = "Options").place(x=150,y=260) myGui.mainloop()
-
Vincent Beltman over 9 years@Rawing You mean in mhello right? Cause _getCurrentOperator already gets it by parameter.
-
Vincent Beltman over 9 yearsOK TY Will edit. I'm always using OOP so I'm not familiar with global.
-
Billy Dawson over 9 yearsThanks for the reply! Having made these changes I'm still experiencing the exact same error
-
Aran-Fey over 9 years@BillyDawson: Did you add
global data
at the top of thereadText
function? -
Billy Dawson over 9 yearsI'd put global data at the start of the program rather than in readText. Having done this there are now no errors but the program doesn't output the broken down equation, nothing appears at all.
-
Aran-Fey over 9 years@BillyDawson: Why would you expect anything to "appear"? You're only appending stuff to your
list
variable. You aren't outputting anything, nor are you modifying the GUI. -
Billy Dawson over 9 yearsI'd originally wanted the print(list) to output stuff for testing purposes, I've managed to fix that now by putting it in the right place. The code works perfectly now! Thanks guys :)
-
Robin over 6 years"It seems that your code is expecting data to be a dictionary." +1
-
Vincent Beltman over 2 yearsI think what may be happening here is that your json is surrounded by quotes, while the quotes inside are escaped
"{\\"key\\":\\"value\\"}"
. In that case, the initial json.loads removes the surrounding quotes and the escape characters, leaving a json object. The second json.loads then parses the json object.