JavaEar 专注于收集分享传播有价值的技术资料

Python - KeyError: 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
            }
         ]
      }
   ]
}

2个回答

    最佳答案
  1. 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
    
  2. 参考答案2
  3. 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