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'}}]
假设我们有:
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'}}]