检查密钥是否存在并使用Python迭代JSON数组

pra*_*avi 111 python json loops

我有一堆来自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"}
Run Code Online (Sandbox Code Playgroud)

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":...}]}
Run Code Online (Sandbox Code Playgroud)

我希望代码打印to_id为1543否则打印'null'

我不知道该怎么做.

谢谢!

ins*_*get 137

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)
Run Code Online (Sandbox Code Playgroud)

输出:

In [9]: getTargetIds(s)
to_id: 1543
Run Code Online (Sandbox Code Playgroud)

  • 为什么这个明确的`in`检查和`raise`如果它们丢失了?只需访问它而不进行检查,您将获得完全相同的行为(除了使用`KeyError`而不是'ValueError`). (5认同)

ath*_*hap 79

如果你想要的只是检查密钥是否存在

h = {'a': 1}
'b' in h # returns False
Run Code Online (Sandbox Code Playgroud)

如果要检查密钥是否有值

h.get('b') # returns None
Run Code Online (Sandbox Code Playgroud)

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

h.get('b', 'Default value')
Run Code Online (Sandbox Code Playgroud)

  • 在 {'a':1, 'b':null} 的情况下,将返回 'null' 而不是 b 预期的 '默认值' (2认同)

Mik*_*keL 15

为这样的事情创建辅助实用程序方法是一个很好的做法,这样无论何时需要更改属性验证的逻辑,它都会在一个地方,并且代码对于关注者来说更具可读性.

例如,在以下位置创建一个辅助方法(或JsonUtils具有静态方法的类)json_utils.py:

def get_attribute(data, attribute, default_value):
    return data.get(attribute) or default_value
Run Code Online (Sandbox Code Playgroud)

然后在您的项目中使用它:

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'))
Run Code Online (Sandbox Code Playgroud)

重要的提示:

我使用的原因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'
Run Code Online (Sandbox Code Playgroud)

在我的应用程序中,获取值为"null"的属性与完全不获取属性相同.如果您的使用情况不同,则需要更改此设置.


小智 13

if "my_data" in my_json_data:
         print json.dumps(my_json_data["my_data"])
Run Code Online (Sandbox Code Playgroud)

  • 这不是一个好的“检查器”,因为你可以有一个键“my_data_whateverasdasdalfhskjhsad”,并且由于子字符串“my_data”,这仍然会返回 True... (3认同)

tab*_*kov 6

我为此编写了一个小函数。随意重新利用,

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

    return True
Run Code Online (Sandbox Code Playgroud)


aba*_*ert 5

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'))
Run Code Online (Sandbox Code Playgroud)

试试吧:

>>> getTargetIds(jsonData)
to_id: 1543
to_id: null
Run Code Online (Sandbox Code Playgroud)

或者,如果您只想跳过值缺少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'])
Run Code Online (Sandbox Code Playgroud)

所以:

>>> getTargetIds(jsonData)
to_id: 1543
Run Code Online (Sandbox Code Playgroud)

当然,在现实生活中,你可能不希望print每个id,但是要存储它们并用它们做一些事情,但这是另一个问题.