简体   繁体   中英

Remove python dict item from nested json file

I have a JSON file that I fetch from an API that returns KeyError:0 while I attempt to remove items in a python dict. I assume its a combination of my lack of skill and format of the json.

My goal is to remove all instances of 192.168.1.1 from ip_address_1

My Code:

from api import Request
import requests, json, ordereddict

# prepare request
request = Request().service('').where({"query":"192.168.1.0"}).withType("json")

# call request
response = request.execute()

# parse response into python object
obj = json.loads(response)

# remove items
for i in xrange(len(obj)):
    if obj[i]["ip_address_1"] == "192.168.1.1":
        obj.pop(i)

# display
print json.dumps(obj,indent=1)

Example JSON:

{
 "response": {
  "alerts": [
   {
    "action": "New",
    "ip_address_1": "192.168.1.1",
    "domain": "example.com",
    "ip_address_2": "192.68.1.2"
   },
   {
    "action": "New",
    "ip_address_1": "192.168.1.3",
    "domain": "example2.com",
    "ip_address_2": "192.168.1.1"
   }
  ],
  "total": "2",
  "query": "192.168.1.0",
 }
}

This is incorrect:

# remove items
for i in xrange(len(obj)):
    if obj[i]["ip_address_1"] == "192.168.1.1":
        obj.pop(i)

You are iterating over an object as if it were a list.

What you want to do:

for sub_obj in obj["response"]["alerts"]:
    if sub_obj["ip_address_1"] == "192.168.1.1":
        sub_obj.pop("ip_address_1")

I've interpreted your requirements to be:

  1. Remove from the "alerts" list any dictionary with ip_address_1 set to 192.168.1.1 .
  2. Create a list of all other ip_address_1 values.

json.loads(response) produces this dictionary:

{u'response': {u'alerts': [{u'action': u'New',
                            u'domain': u'example.com',
                            u'ip_address_1': u'192.168.1.1',
                            u'ip_address_2': u'192.68.1.2'},
                           {u'action': u'New',
                            u'domain': u'example2.com',
                            u'ip_address_1': u'192.168.1.3',
                            u'ip_address_2': u'192.168.1.1'}],
               u'query': u'192.168.1.0',
               u'total': u'2'}}

The "alerts" list is accessed by (assuming the dict is bound to obj ):

>>> obj['response']['alerts']
[{u'action': u'New',
  u'domain': u'example.com',
  u'ip_address_1': u'192.168.1.1',
  u'ip_address_2': u'192.68.1.2'},
 {u'action': u'New',
  u'domain': u'example2.com',
  u'ip_address_1': u'192.168.1.3',
  u'ip_address_2': u'192.168.1.1'}]

The first part can be done like this:

alerts = obj['response']['alerts']
obj['response']['alerts'] = [d for d in alerts if d.get('ip_address_1') != '192.168.1.1']

Here a list comprehension is used to filter out those dictionaries with ip_address_1 192.168.1.1 and the resulting list is then rebound the the obj dictionary. After this obj is:

>>> pprint(obj)
{u'response': {u'alerts': [{u'action': u'New',
                            u'domain': u'example2.com',
                            u'ip_address_1': u'192.168.1.3',
                            u'ip_address_2': u'192.168.1.1'}],
               u'query': u'192.168.1.0',
               u'total': u'2'}}

Next, creating a list of the other ip addresses is easy with another list comprehension run on the alerts list after removing the undesired dicts as shown above:

ip_addresses = [d['ip_address_1'] for d in obj['response']['alerts'] if d.get('ip_address_1') is not None]

Notice that we use get() to handle the possibility that some dictionaries might not have a ip_address_1 key.

>>> ip_addresses
[u'192.168.1.3']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM