web-dev-qa-db-ja.com

キーが存在するかどうかを確認し、Pythonを使用してJSON配列を反復します

私は以下のようなFacebook投稿からのたくさんのJSONデータを持っています。

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

JSONデータは半構造化されており、すべて同じではありません。以下が私のコードです:

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

コードに1543のようにto_idを表示させたい。

私はこれを行う方法がわからない。

ありがとうございます。

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

出力:

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

あなたが望むのはキーが存在するかどうかをチェックすることだけです。

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

Keyに値があるかどうかを確認したい場合

h.get('b') # returns None

実際の値が欠けている場合はデフォルト値を返します

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

属性検証のロジックを変更する必要があるときはいつでもそれが一箇所にあるように、そしてフォロワにとってコードがより読みやすくなるように、そのようなことのためにヘルパーユーティリティメソッドを作成することは良い習慣です。

たとえば、json_utils.pyにヘルパーメソッド(または静的メソッドを含むクラスJsonUtils)を作成します。

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

そしてそれをあなたのプロジェクトで使用します。

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

重要なメモ:

単にdata.get(attribute) or default_valueではなくdata.get(attribute, default_value)を使っているのには理由があります。

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

私のアプリケーションでは、 'null'の値を持つ属性を取得することは、属性をまったく取得しないことと同じです。使い方が違う場合は、これを変更する必要があります。

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

それを試してみてください:

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

あるいは、'null'を出力する代わりに、IDがない値をスキップしたいだけの場合は、次のようにします。

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

そう:

>>> getTargetIds(jsonData)
to_id: 1543

もちろん、実生活では、おそらくそれぞれのIDをprintにするのではなく、それらを保存してそれらを使って何かをしたいのですが、それは別の問題です。

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