2

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",
 }
}
2
  • 1
    It sounds like you want [alert['ip_address_1'] for alert in obj['response']['alerts'] if alert['ip_address_1'] != '192.168.1.1']. Is that a correct interpretation of your question? Commented Feb 24, 2015 at 21:42
  • That was the original logic, however I would like to break it up into two parts, reducing the data set and then printing a section. I'll give the second part another try and post a new question. Commented Feb 24, 2015 at 22:17

2 Answers 2

4

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")
Sign up to request clarification or add additional context in comments.

3 Comments

I receive the following error. Do I need to do something with response before alerts? for sub_obj in obj["alerts"]: KeyError: 'alerts'
What does obj look like? Can you print that out?
{u'response': {u'alerts': [{u'action': u'New', u'ip_address_1': u'192.168.1.1', u'domain': u'example.com', u'ip_address_2': u'192.168.1.2'}, {u'action': u'New'
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']

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.