2014-07-22 6 views
51

Ho un mucchio di dati JSON da Facebook i messaggi come quello qui sotto:Verificare se la chiave esiste e iterare l'array JSON utilizzando Python

{"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"} 

I dati JSON è semi-strutturata e tutto non è la stessa. Qui di seguito è il mio codice:

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":...}]} 

Voglio che il codice per stampare il to_id come 1543 altro print 'nullo'

non sono sicuro come fare questo.

Grazie!

risposta

80
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) 

uscita:

In [9]: getTargetIds(s) 
to_id: 1543 
+2

Perché fare questo esplicito 'tale dicitura controlli e 'rilancio' se mancano? Basta accedervi senza controllo, e otterrete esattamente lo stesso comportamento (tranne con un 'KeyError' invece di un' ValueError'). – abarnert

3
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')) 

Prova ora:

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

O, se si vuole solo saltare valori ids mancanti invece di stampare 'null':

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

Quindi:

>>> getTargetIds(jsonData) 
to_id: 1543 

Naturalmente nella vita reale, probabilmente non si vuole print ogni ID, ma per memorizzarli e fare qualcosa con loro, ma questo è un altro problema.

22

Se tutto quello che volete è quello di verificare se la chiave esiste o no

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

Se si vuole verificare se c'è un valore per la chiave

h.get('b') # returns None 

Ritorna un valore predefinito se il valore effettivo è mancante

h.get('b', 'Default value') 
1

È una buona pratica creare metodi di utilità di supporto per cose del genere in modo che ogni volta che è necessario cambiare la logica della convalida dell'attributo sarebbe in un posto, e il codice sarà più leggibile per i seguaci.

Per esempio creare un metodo di supporto (o classe JsonUtils con metodi statici) in json_utils.py:

def has_attribute(data, attribute): 
    return attribute in data and data[attribute] is not None 

e poi utilizzarlo nel progetto:

from json_utils import has_attribute 

if has_attribute(data, 'to') and has_attribute(data['to'], 'data'): 
    for item in data['to']['data']: 
     if has_attribute(item, 'id'): 
      to_id = item['id'] 
     else: 
      to_id = 'null' 

     print('The id is: %s' % to_id) 
Problemi correlati