Python循序渐进搜索嵌套的键 [英] Python Recursive Search of Dict with Nested Keys
问题描述
globals()
和一个命名的临时全局参数。 我不喜欢使用全局变量。这只是要求注入漏洞。我觉得必须有一个更好的方式来执行这个任务而不诉诸全局变量。
问题数据集:
d = {
k:1,
stuff:s1,
l:{m b $ b {
k:2,
stuff:s2,
l:无
},
{
k:3,
stuff:s3,
l:{m:[
{
k:4,
stuff:s4,
l:无
},
{
k:5,
stuff:s5 ,
l:{m:[
{
k:6,
stuff:s6,
l无
},
]}
},
]}
},
]}
}
所需输出:
[{'k':1,'stuff':'s1'},
{'k':2,'stuff':'s2'},
{'k':3,'stuff':'s3'},
{'k':4,'stuff':'s4'},
{'k'东西':'s5'},
{'k':6,'stuff':'s6'}]
我的解决方案:
def _get_recursive_results(d,iter_key,get_keys):
如果没有全局变量()中的'h':
全局h
h = []
h.append({k:d.get(k)for get inkey)}
d2 = d.copy()
在iter_key中的k:
如果不是d2:
继续
d2 = d2.get(k)
for d2中的td:
d3 = td.copy()
在iter_key中的k:
如果不是d3:
continue
d3 = d3.get(k )
如果d3:
返回_get_recursive_results(td,iter_key,get_ke ys)
h.append({k:td.get(k)for get inkey)}
else:
l = [k for h in h]
del globals( )['h']
return l
如下所示调用我的函数返回所需的结果:
_get_recursively(d,['l','m'],['k','stuff'])
如何构建更好的解决方案?
这是一个略微修改的版本,而不使用全局变量。将 h
设置为无
作为默认值,并为第一次调用创建一个新列表 _get_recursive_results()
。稍后在 _get_recursive_results()
的递归调用中提供 h
作为参数:
def _get_recursive_results(d,iter_key,get_keys,h = None):
如果h为None:
h = []
h .append({k:d.get(k)for get inKeys})
d2 = d.copy()
在iter_key中的k:
如果不是d2:
继续
d2 = d2.get(k)
在d2中的td:
d3 = td.copy()
在iter_key中的k:
如果不是d3:
继续
d3 = d3.get(k)
如果d3:
返回_get_recursive_results(td,iter_key,get_keys,h)
h.append({k: td.get(k)for k in get_keys})
else:
l = [k for h in h]
return l
现在:
>>> _get_recursive_results(d,['l','m'],['k','stuff'])
[{'k':1,'stuff':'s1'},
{ 'k':2,'stuff':'s2'},
{'k':3,'stuff':'s3'},
{'k':4,'stuff' 's4'},
{'k':5,'stuff':'s5'},
{'k':6,'stuff':'s6'}]
不需要复制中间命令。这是一个进一步的修改版本,不复制:
def _get_recursive_results(d,iter_key,get_keys,h = None):
如果h是None,则
h = []
h.append({k:d.get(k)for get inkey)}
在iter_key中的k:
if不是d:
继续
d = d.get(k)
在d中的td:
d3 = td
在iter_key中的k:
如果不是d3:
continue
d3 = d3.get(k)
如果d3:
返回_get_recursive_results(td,iter_key,get_keys,h)
h.append({ k:get_keys中的k的td.get(k)}
else:
return h
I recently had to solve a problem in a real data system with a nested dict/list combination. I worked on this for quite a while and came up with a solution, but I am very unsatisfied. I had to resort to using globals()
and a named temporary global parameter.
I do not like to use globals. That's just asking for an injection vulnerability. I feel that there must be a better way to perform this task without resorting to globals.
Problem Dataset:
d = {
"k":1,
"stuff":"s1",
"l":{"m":[
{
"k":2,
"stuff":"s2",
"l":None
},
{
"k":3,
"stuff":"s3",
"l":{"m":[
{
"k":4,
"stuff":"s4",
"l":None
},
{
"k":5,
"stuff":"s5",
"l":{"m":[
{
"k":6,
"stuff":"s6",
"l":None
},
]}
},
]}
},
]}
}
Desired Output:
[{'k': 1, 'stuff': 's1'},
{'k': 2, 'stuff': 's2'},
{'k': 3, 'stuff': 's3'},
{'k': 4, 'stuff': 's4'},
{'k': 5, 'stuff': 's5'},
{'k': 6, 'stuff': 's6'}]
My Solution:
def _get_recursive_results(d, iter_key, get_keys):
if not 'h' in globals():
global h
h = []
h.append({k:d.get(k) for k in get_keys})
d2 = d.copy()
for k in iter_key:
if not d2:
continue
d2 = d2.get(k)
for td in d2:
d3 = td.copy()
for k in iter_key:
if not d3:
continue
d3 = d3.get(k)
if d3:
return _get_recursive_results(td, iter_key, get_keys)
h.append({k:td.get(k) for k in get_keys})
else:
l = [k for k in h]
del globals()['h']
return l
Calling my function as follows returns the desired result:
_get_recursively(d, ['l','m'], ['k','stuff'])
How would I build a better solution?
This is a slightly modified version without using globals. Set h
to None
as default and create a new list for the first call to _get_recursive_results()
. Later provide h
as an argument in the recursive calls to _get_recursive_results()
:
def _get_recursive_results(d, iter_key, get_keys, h=None):
if h is None:
h = []
h.append({k:d.get(k) for k in get_keys})
d2 = d.copy()
for k in iter_key:
if not d2:
continue
d2 = d2.get(k)
for td in d2:
d3 = td.copy()
for k in iter_key:
if not d3:
continue
d3 = d3.get(k)
if d3:
return _get_recursive_results(td, iter_key, get_keys, h)
h.append({k:td.get(k) for k in get_keys})
else:
l = [k for k in h]
return l
Now:
>>> _get_recursive_results(d, ['l','m'], ['k','stuff'])
[{'k': 1, 'stuff': 's1'},
{'k': 2, 'stuff': 's2'},
{'k': 3, 'stuff': 's3'},
{'k': 4, 'stuff': 's4'},
{'k': 5, 'stuff': 's5'},
{'k': 6, 'stuff': 's6'}]
There is no need for the copying of intermediate dicts. This is a further modified version without copying:
def _get_recursive_results(d, iter_key, get_keys, h=None):
if h is None:
h = []
h.append({k: d.get(k) for k in get_keys})
for k in iter_key:
if not d:
continue
d = d.get(k)
for td in d:
d3 = td
for k in iter_key:
if not d3:
continue
d3 = d3.get(k)
if d3:
return _get_recursive_results(td, iter_key, get_keys, h)
h.append({k: td.get(k) for k in get_keys})
else:
return h
这篇关于Python循序渐进搜索嵌套的键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!