检查 key 是否存在,并使用 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,否则打印’空’

我不知道该怎么做。

458678 次浏览
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
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

或者,如果您只是想跳过缺少 id 的值而不是打印 'null':

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

当然,在现实生活中,您可能不希望 print每个 id,但是要存储它们并对它们进行处理,但是这是另一个问题。

如果您想要的只是检查键是否存在

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

如果要检查键是否有值

h.get('b') # returns None

如果缺少实际值,则返回默认值

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

为类似的事情创建 helper 实用工具方法是一个很好的实践,这样无论何时您需要更改属性验证的逻辑,它都会在一个地方,并且代码对于跟随者来说更具可读性。

例如,在 json_utils.py中创建一个 helper 方法(或者使用静态方法创建类 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’的属性与根本不获取属性是一样的。如果您的用法不同,则需要更改此项。

if "my_data" in my_json_data:
print json.dumps(my_json_data["my_data"])

我为此编写了一个小函数,你可以重新定义,

def is_json_key_present(json, key):
try:
buf = json[key]
except KeyError:
return False


return True

你可以试试-除了

try:
print(str.to.id)
except AttributeError: # Not a Retweet
print('null')