首页 > 解决方案 > Python:在嵌套字典列表中搜索嵌套字典列表

问题描述

假设我们有:

stack = [
         {'id': '1', 'name': {'firstname': 'bob', 'lastname': 'smith'}},
         {'id': '2', 'name': {'firstname': 'jane', 'lastname': 'abb'}},
         {'id': '3', 'name': {'firstname': 'flo', 'lastname': 'gram', 'middle': 'remi'}},
         {'id': '4', 'name': {'firstname': 'frank', 'lastname': 'glow'}, 'partner': 'diane'}
]
needles = [{'name':{'lastname': 'gram'}},
          {'partner': 'diane'}
]

我们想要一个函数 find,如下所示:

list = find(needles, stack)
print(list)
>[{id: '3', name: {firstname: 'flo', lastname: 'gram', middle: 'remi'}}, {id: '4', name: {firstname: 'frank', lastname: 'glow'}, partner: 'diane'}]

起初我想使用 items(),如下所示:

def find(needle, stack):
    result = []
    for needle in needles:
        for item in stack:
            if needle.items() <= item.items():
                result.append()

但这会返回:

[{'id': '4', 'name': {'firstname': 'frank', 'lastname': 'glow'}, 'partner': 'diane'}]

因为项目匹配必须准确,所以我必须通过['name': {'firstname': 'flo', 'lastname': 'gram', 'middle': 'remi'}, {'partner': 'diane'}'我的函数才能返回所需的结果。

我不知道从这里去哪里。由于我的堆栈可以嵌套未知深度({a:{b:{c:value}}}),因此解决方案可能是某种递归,但可能没有必要,因为我想检查确切的“路径” (键)在针中。归结为将针状物品与堆叠物品部分匹配。

标签: pythonlistdictionarysearchnested

解决方案


您可以使用递归:

def find(n, s):
   def exists(n, d):
      if type(n) != type(d):
         return False
      if not isinstance(n, (dict, list)):
          return n == d
      if isinstance(n, list):
          return any(exists(j, k) for j in n for k in d)
      return all(exists(b, d.get(a, None)) for a, b in n.items())
   return [i for i in s if any(exists(j, i) for j in n)]

stack = [{'id': '1', 'name': {'firstname': 'bob', 'lastname': 'smith'}}, {'id': '2', 'name': {'firstname': 'jane', 'lastname': 'abb'}}, {'id': '3', 'name': {'firstname': 'flo', 'lastname': 'gram', 'middle': 'remi'}}, {'id': '4', 'name': {'firstname': 'frank', 'lastname': 'glow'}, 'partner': 'diane'}, {'id': '5', 'name': {'firstname': ['flo', 'Flo'], 'lastname': 'gram', 'middle': 'remi'}}]
needles = [{'name': {'lastname': 'gram'}}, {'partner': 'diane'}, {'name':{'firstname':['Flo']}}]
results = find(needles, stack)

输出:

[{'id': '3', 'name': {'firstname': 'flo', 'lastname': 'gram', 'middle': 'remi'}}, 
 {'id': '4', 'name': {'firstname': 'frank', 'lastname': 'glow'}, 'partner': 'diane'}, 
 {'id': '5', 'name': {'firstname': ['flo', 'Flo'], 'lastname': 'gram', 'middle': 'remi'}}]

推荐阅读