I get this error "TypeError: string indices must be integers" when defining a variable.
def updateJson(fileName, pathToValue, updatedValue):
# Opening JSON file
f = open(fileName)
# returns JSON object as a dictionary
data = json.load(f)
# Changes the ID value in JSON
data[pathToValue] = updatedValue
f.close()
with open("template3.json", "w") as outfile:
json.dump(data, outfile)
x = ['Something 1'][0]['ID']
updateJson("Temp\\random.json", x, 9)
JSON:
{
"Something 1": [
{
"ID": "placeholder",
"Music": "placeholder"
}
]
}
But if I don't pass it as variable and just use it in code like this: data['Something 1'][0]['ID'] = updatedValue
it works as expected.
What I have tried:
Wrapping the variable in ""
, ()
, {}
and some other minor things, in which case it kinda works, but the path gets interpreted wrong, and I can't successfully target the ID value in JSON.
CodePudding user response:
The problem has nothing to do with your JSON. Consider the following code:
y = "Some string"["ID"]
This wouldn't work, right? something like y = "Some string"[1]
would set y
equal to "o"
, but the example above is nonsensical.
When you are defining x
, this is what's happening. Let's break it down:
x = ["Something 1"]
# x is a list, containing a single string
x = ["Something 1"][0]
# x is the first element of the list ["Something 1"], so x = "Something 1" - see for yourself!
x = ["Something 1"][0]["ID"]
# TypeError! This is equivalent to:
x = "Something 1"["ID"]
To get the functionality you're looking for, we need another way to pass this pathToValue. One way to do this is to pass the different parts as different parameters:
def updateJson(fileName, pathMain, pathIndex, pathMinor, updatedValue):
...
data[pathMain][pathIndex][pathMinor] = updatedValue
...
updateJson("Temp \\random.json", "Something 1", 0, "ID", 9) # Would work
However, this would only work if your JSON file has a very consistent structure.
A slightly more concise way to do this would be:
def updateJson(fileName, pathToValue, updatedValue):
...
pathMain, pathIndex, pathMinor = pathToValue # Extract the different components of pathToValue from the list
data[pathMain][pathIndex][pathMinor] = updatedValue
...
x = ["Something 1", 0, "ID"]
updateJson("Temp \\random.json", x, 9) # Would work
CodePudding user response:
The command bellow does the following:
- Creates a list with one item of type str and value "Something 1"
- Takes the first element of the list ("Something 1")
- Tries to get the element "ID" from "Something 1" and thus the error
x = ['Something 1'][0]['ID']
you will need to get these from another object, that holds the JSON data you expect.
Try instead to define a function that applies the path to the right variable. Like this:
def updateJson(fileName, update, updatedValue):
# Opening JSON file
f = open(fileName)
# returns JSON object as a dictionary
data = json.load(f)
# Changes the ID value in JSON
update(data, updatedValue)
f.close()
with open("template3.json", "w") as outfile:
json.dump(data, outfile)
x = lambda data, value: data["Something 1"][0].setdefault("ID", value)
updateJson("Temp\\random.json", x, 9)