2014-07-22 8 views
51

Mam pęczek danych JSON za posty na Facebooku, jak ten poniżej:Sprawdź, czy klucz istnieje i iterację tablicę JSON przy użyciu 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"} 

dane JSON jest pół-strukturalnego i nie wszystko jest takie same. Poniżej jest mój kod:

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

Chcę kod aby wydrukować to_id jak 1543 else print 'null'

nie jestem pewien, jak to zrobić.

Dzięki!

Odpowiedz

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) 

wyjściowa:

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

Dlaczego to wyraźny 'in' kontroli i "przebić", jeśli ich brakuje? Wystarczy uzyskać do niego dostęp bez sprawdzania, a otrzymasz dokładnie to samo zachowanie (z wyjątkiem 'KeyError' zamiast' 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')) 

Spróbuj:

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

Albo, jeśli chcesz po prostu przeskoczyć wartości brakujące identyfikatory zamiast drukować 'null':

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

Więc:

>>> getTargetIds(jsonData) 
to_id: 1543 

oczywiście w prawdziwym życiu, to prawdopodobnie nie chcą print Każdy identyfikator, ale do ich przechowywania i zrobić coś z nimi, ale to już inna kwestia.

22

Jeśli chcesz to sprawdzić, czy klucz istnieje, czy nie

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

Jeśli chcesz sprawdzić, czy istnieje wartość dla klucza

h.get('b') # returns None 

zwrócić wartość domyślną, jeśli wartość rzeczywista jest brakuje

1

Dobrą praktyką jest tworzenie pomocniczych metod użytkowych dla takich rzeczy, aby zawsze, gdy trzeba zmiana logiki sprawdzania poprawności atrybutu będzie w jednym miejscu, a kod będzie bardziej czytelny dla obserwujących.

Na przykład utworzyć metody pomocnika (lub klasę JsonUtils z metod statycznych) w json_utils.py:

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

a następnie użyć go w swoim projekcie:

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) 
Powiązane problemy