web-dev-qa-db-fra.com

Vérifiez si la clé existe et parcourez le tableau JSON à l'aide de Python

J'ai un tas de données JSON de posts Facebook comme celui ci-dessous:

{"from": {"id": "8", "name": "Mary Pinter"}, "message": "How ARE you?", "comments": {"count": 0}, "updated_time": "2012-05-01", "created_time": "2012-05-01", "to": {"data": [{"id": "1543", "name": "Honey Pinter"}]}, "type": "status", "id": "id_7"}

Les données JSON sont semi-structurées et toutes différentes. Ci-dessous mon code:

import json 

str = '{"from": {"id": "8", "name": "Mary Pinter"}, "message": "How ARE you?", "comments": {"count": 0}, "updated_time": "2012-05-01", "created_time": "2012-05-01", "to": {"data": [{"id": "1543", "name": "Honey Pinter"}]}, "type": "status", "id": "id_7"}'
data = json.loads(str)

post_id = data['id']
post_type = data['type']
print(post_id)
print(post_type)

created_time = data['created_time']
updated_time = data['updated_time']
print(created_time)
print(updated_time)

if data.get('application'):
    app_id = data['application'].get('id', 0)
    print(app_id)
else:
    print('null')

#if data.get('to'):
#... This is the part I am not sure how to do
# Since it is in the form "to": {"data":[{"id":...}]}

Je veux que le code affiche le to_id comme 1543 sinon, affiche 'null'

Je ne sais pas comment faire cela.

Merci!

102
pravi
import json

jsonData = """{"from": {"id": "8", "name": "Mary Pinter"}, "message": "How ARE you?", "comments": {"count": 0}, "updated_time": "2012-05-01", "created_time": "2012-05-01", "to": {"data": [{"id": "1543", "name": "Honey Pinter"}]}, "type": "status", "id": "id_7"}"""

def getTargetIds(jsonData):
    data = json.loads(jsonData)
    if 'to' not in data:
        raise ValueError("No target in given data")
    if 'data' not in data['to']:
        raise ValueError("No data for target")

    for dest in data['to']['data']:
        if 'id' not in dest:
            continue
        targetId = dest['id']
        print("to_id:", targetId)

Sortie:

In [9]: getTargetIds(s)
to_id: 1543
127
inspectorG4dget

Si tout ce que vous voulez est de vérifier si la clé existe ou non

h = {'a': 1}
'b' in h # returns False

Si vous voulez vérifier s'il y a une valeur pour la clé

h.get('b') # returns None

Renvoie une valeur par défaut si la valeur réelle est manquante.

h.get('b', 'Default value')
75
athap

C'est une bonne pratique de créer des méthodes utilitaires d'aide pour des choses de ce genre, afin que, chaque fois que vous devez modifier la logique de validation des attributs, celle-ci se trouve à un endroit et le code sera plus lisible par les suiveurs.

Par exemple, créez une méthode d'assistance (ou la classe JsonUtils avec des méthodes statiques) dans json_utils.py:

def get_attribute(data, attribute, default_value):
    return data.get(attribute) or default_value

puis utilisez-le dans votre projet:

from json_utils import get_attribute

def my_cool_iteration_func(data):

    data_to = get_attribute(data, 'to', None)
    if not data_to:
        return

    data_to_data = get_attribute(data_to, 'data', [])
    for item in data_to_data:
        print('The id is: %s' % get_attribute(item, 'id', 'null'))

NOTE IMPORTANTE:

Il y a une raison pour laquelle j'utilise data.get(attribute) or default_value au lieu de simplement data.get(attribute, default_value):

{'my_key': None}.get('my_key', 'nothing') # returns None
{'my_key': None}.get('my_key') or 'nothing' # returns 'nothing'

Dans mes applications, l'attribut avec la valeur 'null' revient à ne pas obtenir l'attribut du tout. Si votre utilisation est différente, vous devez changer cela.

13
MikeL
jsonData = """{"from": {"id": "8", "name": "Mary Pinter"}, "message": "How ARE you?", "comments": {"count": 0}, "updated_time": "2012-05-01", "created_time": "2012-05-01", "to": {"data": [{"id": "1543", "name": "Honey Pinter"}, {"name": "Joe Schmoe"}]}, "type": "status", "id": "id_7"}"""

def getTargetIds(jsonData):
    data = json.loads(jsonData)
    for dest in data['to']['data']:
        print("to_id:", dest.get('id', 'null'))

Essayez le:

>>> getTargetIds(jsonData)
to_id: 1543
to_id: null

Ou, si vous voulez simplement ignorer les valeurs manquantes au lieu d'imprimer 'null':

def getTargetIds(jsonData):
    data = json.loads(jsonData)
    for dest in data['to']['data']:
        if 'id' in to_id:
            print("to_id:", dest['id'])

Alors:

>>> getTargetIds(jsonData)
to_id: 1543

Bien sûr, dans la vie réelle, vous ne voulez probablement pas print chaque identifiant, mais les stocker et en faire quelque chose, mais c’est un autre problème.

5
abarnert
if "my_data" in my_json_data:
         print json.dumps(my_json_data["my_data"])
1
Ajit Surendran