Python 3 JSON - 按值而不是索引选择?

时间:2016-04-20 17:32:19

标签: python json

我在JSON文件中获得了一些我试图操作的数据。由于之前没有对JSON做过多少工作,我想知道是否有可能通过其中一个值而不是索引来选择一个对象。

这是我的json文件:

{"device":[
    {"id": 0, "name": "iPhone 6", "width": 750, "height": 1334},
    {"id": 1, "name": "iPhone 6 Plus", "width": 1242, "height": 2208},
    {"id": 2, "name": "Galaxy S6", "width": 1440, "height": 2560}
]}

我想选择id = 0的对象并打印出name值。我意识到执行此操作的典型方法是通过其索引值选择对象,在这种情况下,该值与id值匹配,这意味着我会执行以下操作:

print(json_obj['device'][0]['name'])

这将打印名称,但它依赖于索引等于id,在理想的世界中它将是。也许更好的方法是将索引作为id并完全删除该字段,这样就没有混淆了?现在看起来像是一个重复的索引,虽然它存在,所以我可以在我的数据库中存储一个ID并在JSON文件中独立编辑name但是有一些具体的东西来表示顺序(即有人可能将设备添加到文件的顶部,从而改变每个其他设备的索引 - 打破整个系统。我感觉自己咆哮了错误的数据结构,并且无法按照以下方式做某事:

print(json_obj['device'][id = 0]['name']

我是对的吗?

3 个答案:

答案 0 :(得分:3)

次要注意:这与JSON无关。一旦您解析了数据,它就不再是JSON,而是它在内存中的常规数据(列表,字符串,字典等)

一个简单的方法是使用循环:

for device in data['device']:
    if device['id'] == 5:
        print('Device:', device['name'])
        break
else:
    print('No such device')

你也可以用理解或其他复杂(和简洁)的方式来做到这一点,但上面的方法可能更直接和简单。

还有一个名为JSONPath的系统(带有Python module),可让您以更具声明性和自然的方式表达查询。

答案 1 :(得分:0)

显然没有什么效果,但你可以这样做:

[x['name'] for x in json_obj['device'] if x['id'] == 0][0]

这会构建一个id == 0的所有元素的列表。在 id not found 的情况下,它更难处理。

从设计的角度来看,如果您可以控制数据的来源,或者您可能想要处理它,那就更像是:

{'device': {
    0: {"id": 0, "name": "iPhone 6", "width": 750, "height": 1334},
    1: {"id": 1, "name": "iPhone 6 Plus", "width": 1242, "height": 2208},
    2: {"id": 2, "name": "Galaxy S6", "width": 1440, "height": 2560}
    }
}

如果你没有控制权,你可以通过以下方式到达目的地:

json_obj['device'] = dict(zip([x['id'] for x in json_obj['device']), json_obj['device'])
json_obj['device'][id]['name']

在实践中,您可能不想覆盖现有变量,但这样可以使其他所有变量保持不变。

答案 2 :(得分:0)

肯定有很多简单的方法可以做到这一点。

data = {
    "device": [
        {"id": 0, "name": "iPhone 6", "width": 750, "height": 1334},
        {"id": 1, "name": "iPhone 6 Plus", "width": 1242, "height": 2208},
        {"id": 2, "name": "Galaxy S6", "width": 1440, "height": 2560}
    ]
}

items = data.get('device')
for item in items:
    if item.get('id') == 0:
        print(item.get('name'))
相关问题