Tengo un archivo JSON que obtengo de una API que devuelve KeyError: 0 mientras bash eliminar elementos en un dict de python. Supongo que es una combinación de mi falta de habilidad y formato del json.
Mi objective es eliminar todas las instancias de 192.168.1.1
de ip_address_1
Mi código:
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)
Ejemplo 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", } }
Esto es incorrecto:
# remove items for i in xrange(len(obj)): if obj[i]["ip_address_1"] == "192.168.1.1": obj.pop(i)
Estás iterando sobre un objeto como si fuera una lista.
Que quieres hacer:
for sub_obj in obj["response"]["alerts"]: if sub_obj["ip_address_1"] == "192.168.1.1": sub_obj.pop("ip_address_1")
He interpretado tus requerimientos para ser:
ip_address_1
configurado en 192.168.1.1
. ip_address_1
. json.loads(response)
produce este diccionario:
{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'}}
Se accede a la lista de “alertas” por (asumiendo que el dictado está obligado a 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'}]
La primera parte se puede hacer así:
alerts = obj['response']['alerts'] obj['response']['alerts'] = [d for d in alerts if d.get('ip_address_1') != '192.168.1.1']
Aquí se usa una lista de comprensión para filtrar esos diccionarios con ip_address_1
192.168.1.1 y la lista resultante es luego rebotar en el diccionario de obj
. Después de este obj
es:
>>> 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'}}
A continuación, es fácil crear una lista de las otras direcciones IP con otra comprensión de lista ejecutada en la lista de alertas después de eliminar los dicts no deseados como se muestra arriba:
ip_addresses = [d['ip_address_1'] for d in obj['response']['alerts'] if d.get('ip_address_1') is not None]
Tenga en cuenta que usamos get()
para manejar la posibilidad de que algunos diccionarios no tengan una clave ip_address_1
.
>>> ip_addresses [u'192.168.1.3']