manipulate - python json navigation
Analizando a json y buscando a través de él. (5)
Como json.loads
simplemente devuelve un dict, puede usar los operadores que aplican a los dicts:
>>> jdata = json.load(''{"uri": "http:", "foo", "bar"}'')
>>> ''uri'' in jdata # Check if ''uri'' is in jdata''s keys
True
>>> jdata[''uri''] # Will return the value belonging to the key ''uri''
u''http:''
Editar: para dar una idea sobre cómo recorrer los datos, considere el siguiente ejemplo:
>>> import json
>>> jdata = json.loads(open (''bookmarks.json'').read())
>>> for c in jdata[''children''][0][''children'']:
... print ''Title: {}, URI: {}''.format(c.get(''title'', ''No title''),
c.get(''uri'', ''No uri''))
...
Title: Recently Bookmarked, URI: place:folder=BOOKMARKS_MENU(...)
Title: Recent Tags, URI: place:sort=14&type=6&maxResults=10&queryType=1
Title: , URI: No uri
Title: Mozilla Firefox, URI: No uri
La inspección de la estructura de datos jdata
le permitirá navegar por ella como desee. La llamada de pprint
que ya tiene es un buen punto de partida para esto.
Edit2: Otro intento. Esto obtiene el archivo que mencionaste en una lista de diccionarios. Con esto, creo que deberías poder adaptarlo a tus necesidades.
>>> def build_structure(data, d=[]):
... if ''children'' in data:
... for c in data[''children'']:
... d.append({''title'': c.get(''title'', ''No title''),
... ''uri'': c.get(''uri'', None)})
... build_structure(c, d)
... return d
...
>>> pprint.pprint(build_structure(jdata))
[{''title'': u''Bookmarks Menu'', ''uri'': None},
{''title'': u''Recently Bookmarked'',
''uri'': u''place:folder=BOOKMARKS_MENU&folder=UNFILED_BOOKMARKS&(...)''},
{''title'': u''Recent Tags'',
''uri'': u''place:sort=14&type=6&maxResults=10&queryType=1''},
{''title'': u'''', ''uri'': None},
{''title'': u''Mozilla Firefox'', ''uri'': None},
{''title'': u''Help and Tutorials'',
''uri'': u''http://www.mozilla.com/en-US/firefox/help/''},
(...)
}]
Para luego "buscar a través de él para u''uri'': u''http:''
" , haga algo como esto:
for c in build_structure(jdata):
if c[''uri''].startswith(''http:''):
print ''Started with http''
Tengo este codigo
import json
from pprint import pprint
json_data=open(''bookmarks.json'')
jdata = json.load(json_data)
pprint (jdata)
json_data.close()
¿Cómo puedo buscar a través de él para u''uri'': u''http:
:?
Funciones para buscar e imprimir dictados, como JSON. * hecho en python 3
Buscar:
def pretty_search(dict_or_list, key_to_search, search_for_first_only=False):
"""
Give it a dict or a list of dicts and a dict key (to get values of),
it will search through it and all containing dicts and arrays
for all values of dict key you gave, and will return you set of them
unless you wont specify search_for_first_only=True
:param dict_or_list:
:param key_to_search:
:param search_for_first_only:
:return:
"""
search_result = set()
if isinstance(dict_or_list, dict):
for key in dict_or_list:
key_value = dict_or_list[key]
if key == key_to_search:
if search_for_first_only:
return key_value
else:
search_result.add(key_value)
if isinstance(key_value, dict) or isinstance(key_value, list) or isinstance(key_value, set):
_search_result = pretty_search(key_value, key_to_search, search_for_first_only)
if _search_result and search_for_first_only:
return _search_result
elif _search_result:
for result in _search_result:
search_result.add(result)
elif isinstance(dict_or_list, list) or isinstance(dict_or_list, set):
for element in dict_or_list:
if isinstance(element, list) or isinstance(element, set) or isinstance(element, dict):
_search_result = pretty_search(element, key_to_search, search_result)
if _search_result and search_for_first_only:
return _search_result
elif _search_result:
for result in _search_result:
search_result.add(result)
return search_result if search_result else None
Impresión:
def pretty_print(dict_or_list, print_spaces=0):
"""
Give it a dict key (to get values of),
it will return you a pretty for print version
of a dict or a list of dicts you gave.
:param dict_or_list:
:param print_spaces:
:return:
"""
pretty_text = ""
if isinstance(dict_or_list, dict):
for key in dict_or_list:
key_value = dict_or_list[key]
if isinstance(key_value, dict):
key_value = pretty_print(key_value, print_spaces + 1)
pretty_text += "/t" * print_spaces + "{}:/n{}/n".format(key, key_value)
elif isinstance(key_value, list) or isinstance(key_value, set):
pretty_text += "/t" * print_spaces + "{}:/n".format(key)
for element in key_value:
if isinstance(element, dict) or isinstance(element, list) or isinstance(element, set):
pretty_text += pretty_print(element, print_spaces + 1)
else:
pretty_text += "/t" * (print_spaces + 1) + "{}/n".format(element)
else:
pretty_text += "/t" * print_spaces + "{}: {}/n".format(key, key_value)
elif isinstance(dict_or_list, list) or isinstance(dict_or_list, set):
for element in dict_or_list:
if isinstance(element, dict) or isinstance(element, list) or isinstance(element, set):
pretty_text += pretty_print(element, print_spaces + 1)
else:
pretty_text += "/t" * print_spaces + "{}/n".format(element)
else:
pretty_text += str(dict_or_list)
if print_spaces == 0:
print(pretty_text)
return pretty_text
Parece que hay un error tipográfico (dos puntos que faltan) en el dictado JSON proporcionado por jro.
La sintaxis correcta sería: jdata = json.load (''{"uri": "http:", "foo": "bar"}'')
Esto lo aclaré cuando jugaba con el código.
Puede usar jsonpipe si solo necesita la salida (y más cómodo con la línea de comandos):
cat bookmarks.json | jsonpipe |grep uri
ObjectPath es una biblioteca que proporciona la capacidad de consultar estructuras JSON y anidadas de dictados y listas. Por ejemplo, puede buscar todos los atributos llamados "foo" sin importar qué tan profundos estén usando $..foo
.
Si bien la documentación se centra en la interfaz de línea de comandos, puede realizar las consultas mediante programación utilizando las partes internas de Python del paquete. El siguiente ejemplo asume que ya ha cargado los datos en las estructuras de datos de Python (listas y listas). Si está comenzando con un archivo o cadena JSON , primero necesita usar la load
o las loads
del módulo json .
import objectpath
data = [
{''foo'': 1, ''bar'': ''a''},
{''foo'': 2, ''bar'': ''b''},
{''NoFooHere'': 2, ''bar'': ''c''},
{''foo'': 3, ''bar'': ''d''},
]
tree_obj = objectpath.Tree(data)
tuple(tree_obj.execute(''$..foo''))
# returns: (1, 2, 3)
Tenga en cuenta que simplemente se saltaron elementos que carecían de un atributo "foo", como el tercer elemento de la lista. También puede hacer consultas mucho más complejas, lo que hace que ObjectPath sea útil para estructuras profundamente anidadas (por ejemplo, encontrar dónde x tiene y que tiene z: $.xyz
). Te remito a la documentation y al tutorial para más información.