首页 > 解决方案 > 使用 Python 从 json 中查找多个条目的最快方法

问题描述

我有一个包含大约 50k 项的 JSON,其中每个项都有一个 id 和名称,如下所示(我剪切了数据):

[
    {
      "id": 2,
      "name": "Cannonball"
    },
    {
      "id": 6,
      "name": "Cannon base"
    },
    {
      "id": 8,
      "name": "Cannon stand"
    },
    {
      "id": 10,
      "name": "Cannon barrels"
    },
    {
      "id": 12,
      "name": "Cannon furnace"
    },
    {
      "id": 28,
      "name": "Insect repellent"
    },
    {
      "id": 30,
      "name": "Bucket of wax"
    }]

现在,我有一个项目名称数组,我想找到相应的 id 并将其添加到 id 数组中。

例如,我有itemName = ['Cannonball', 'Cannon furnace', 'Bucket of wax]

我想在 JSON 中搜索并返回id_array = [2, 12, 30]

我编写了以下代码来完成这项工作,但这似乎是一种巨大的能源浪费:

file_name = "database.json"
with open(file_name, 'r') as f:
    document =  json.loads(f.read())

items = ['Cannonball', 'Cannon furnace','Bucket of wax']
for item_name in items:
    for entry in document:
            if item_name == entry ['name']:
                id_array.append(entry ['id'])

有没有更快的方法可以做到这一点?

上面的例子只显示了 3 个结果,但我说的是几千个,迭代超过 1k+ 个结果感觉像是浪费。

谢谢

标签: pythonjson

解决方案


构建一个lookup将名称映射到 id 的字典,然后在该字典中查找名称:

lookup = { d["name"] : d["id"] for d in document}

items = ['Cannonball', 'Cannon furnace','Bucket of wax']

result = [lookup[item] for item in items]
print(result)

输出

[2, 12, 30]

这种方法的时间复杂度是文档O(n + m)n的元素数 ( len(document)) 和m项目数 ( len(items)),相比之下,您的方法是O(nm)

另一种使用更少空间的方法是过滤掉那些不在项目中的名称:

items = ['Cannonball', 'Cannon furnace', 'Bucket of wax']
item_set = set(items)

lookup = {d["name"]: d["id"] for d in document if d["name"] in item_set}
result = [lookup[item] for item in items]

这种方法与前一种方法具有相同的时间复杂度。


推荐阅读