Home > Enterprise >  Error when defining a dictionary path as a variable: TypeError: string indices must be integers
Error when defining a dictionary path as a variable: TypeError: string indices must be integers

Time:09-23

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:

  1. Creates a list with one item of type str and value "Something 1"
  2. Takes the first element of the list ("Something 1")
  3. 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) 
  • Related