0

I keep getting KeyError: 0 every time I run this code I don't know if it can't find "title": "Screenshots" in the json file or what so any help will be welcomed. Thanks!

Code:

import json

obj  = json.load(open("path/to/json/file"))

# Iterate through the objects in the JSON and pop (remove)
# the obj once we find it.
for i in range(len(obj)):
    if obj[i]["title"] == "Screenshots":
        obj.pop(i)
        break

open("path/to/json/file", "w").write(
    json.dumps(obj, sort_keys=True, indent=4, separators=(',', ': '))
)

JSON File:

{
   "minVersion": "0.1",
   "class": "DepictionTabView",
   "tintColor": "#2cb1be",
   "headerImage": "",
   "tabs": [
      {
         "tabname": "Details",
         "class": "DepictionStackView",
         "tintColor": "#2cb1be",
         "views": [
            {
               "class": "DepictionSubheaderView",
               "useBoldText": true,
               "useBottomMargin": false,
               "title": "Description"
            },
            {
               "class": "DepictionMarkdownView",
               "markdown": "Some dummy text...",
               "useRawFormat": true
            },
            {
               "class": "DepictionSeparatorView"
            },
            {
               "class": "DepictionSubheaderView",
               "useBoldText": true,
               "useBottomMargin": false,
               "title": "Screenshots"
            },
            {
               "class": "DepictionScreenshotsView",
               "itemCornerRadius": 6,
               "itemSize": "{160, 284.44444444444}",
               "screenshots": [
                  {
                     "accessibilityText": "Screenshot",
                     "url": "http://example.com/image.png",
                  }
               ]
            },
            {
               "class": "DepictionSeparatorView"
            },
            {
               "class": "DepictionSubheaderView",
               "useBoldText": true,
               "useBottomMargin": false,
               "title": "Information"
            },
            {
               "class": "DepictionTableTextView",
               "title": "Author",
               "text": "User"
            },
            {
               "class": "DepictionSpacerView",
               "spacing": 16
            },
            {
               "class": "DepictionStackView",
               "views": [
                  {
                     "class": "DepictionTableButtonView",
                     "title": "Contact",
                     "action": "http://example.com/",
                     "openExternal": true
                  }
               ]
            },
            {
               "class": "DepictionSpacerView",
               "spacing": 16
            }
         ]
      },
      {
         "tabname": "History",
         "class": "DepictionStackView",
         "views": [
            {
               "class": "DepictionSubheaderView",
               "useBoldText": true,
               "useBottomMargin": false,
               "title": ""
            },
            {
               "class": "DepictionMarkdownView",
               "markdown": "<ul>\n<li>Initial release.<\/li>\n<\/ul>",
               "useRawFormat": true
            }
         ]
      }
   ]
}
0

2 Answers 2

3

The way you're reading it in, obj is a dict. You're trying to access it as a list, with integer indices. This code:

for i in range(len(obj)):
    if obj[i]["title"] == "Screenshots":
        ...

first calls obj[0]["title"], then obj[1]["title"], and so on. Since obj is not a list, 0 here is interpreted here as a key - and since obj doesn't have a key 0, you get a KeyError.

A better way to do this would be to iterate through the dict by keys and values:

for k, v in obj.items():
    if v["title"] == "Screenshots":  # index using the value
        obj.pop(k)                   # delete the key
Sign up to request clarification or add additional context in comments.

4 Comments

Keep in mind that this answer tells you why you're receiving the KeyError, but will not fix the rest of your code. You need to carefully consider the structure of your dict and how far into it you're trying to iterate - the code you've presented, even when fixed with my solution, will run into another KeyError: "title", because "title" isn't a key in the outer-level obj either. But now that you know that, you should be able to write your code to compensate.
I get this error TypeError: string indices must be integers
oh, right, if v isn't a dict itself, that error will happen. You could instead do if type(v) != str and v["title"] == "Screenshots": to avoid that kind of error.
Little confused could you please explain more
0

In your loop, range yields integers, the first being 0. The is no integer as key in your json so this immediately raises a KeyError.

Instead, loop over obj.items() which yields key-value pairs. Since some of your entries are not dict themselves, you will need to be careful with accessing obj[i]['title'].

for k, v in obj.items():
    if isinstance(v, dict) and v.get("title") == "Screenshots":
        obj.pop(k)
        break

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.