Python: 在嵌套字典列表中搜索嵌套字典列表

Python: Search for a list of nested dict in a list of nested dict

假设我们有:

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()

但是这个 returns:

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

因为项目匹配必须精确,所以我必须将 ['name': {'firstname': 'flo', 'lastname': 'gram', 'middle': 'remi'}, {'partner': 'diane'}' 传递给 return 所需的结果。

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

你可以使用递归:

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'}}]