<p>这段代码使用递归生成器进行搜索,因此它将在找到它们时生成所有的解决方案。在</p>
<p>当<code>iterate_dict</code>找到具有所需(键、值)对的dict时,它调用<code>filter_dict</code>,这将创建一个新dict来包含输出。这个新dict包含传递给<code>filter_dict</code>的dict项,除了过滤掉所需的(键、值)对之外,它还过滤掉该dict可能包含的任何列表或dict。但是,<code>iterate_dict</code>将递归地处理这些列表或dict,以寻找进一步的匹配项。如果您不希望<code>iterate_dict</code>查找进一步的匹配项,那么可以很容易地修改代码,这样就不会这样做;请参见下面的内容。在</p>
<p>如果要搜索包含所需键的dict,而不关心与该键相关联的值,可以将<code>None</code>作为<code>val</code>参数传递,或者忽略该参数。在</p>
<p>我稍微修改了您的数据,这样我们就可以在包含匹配项的dict中测试递归搜索进一步的匹配项。在</p>
<pre><code>def filter_dict(d, key):
return {k: v for k, v in d.items()
if k != key and not isinstance(v, (dict, list))}
def iterate_dict(d, key, val=None):
if key in d and (val is None or d[key] == val):
yield filter_dict(d, key)
yield from iterate_list(d.values(), key, val)
def iterate_list(seq, key, val):
for v in seq:
if isinstance(v, list):
yield from iterate_list(v, key, val)
elif isinstance(v, dict):
yield from iterate_dict(v, key, val)
# test
data = {
'abc': {
'bcd': [
{'cde':'100', 'def':'200', 'efg':'300'},
{'cde':'3000', 'def':'500', 'efg':'4000'},
{'abc': '1', 'mnx': '2', 'ijk': '3',
'zzz': {'xyzz':'44', 'mnx':'e838', 'yew':'55'}
},
],
'ghi': {
'mnc': [
{'xyz':'8827382', 'mnx':'e838', 'wyew':'2232'}
]
}
}
}
for d in iterate_dict(data, 'mnx', 'e838'):
print(d)
</code></pre>
<p><strong>输出</strong></p>
^{pr2}$
<p>以下是搜索包含<code>'mnx'</code>键的所有dict:</p>
<pre><code>for d in iterate_dict(data, 'mnx'):
print(d)
</code></pre>
<p><strong>输出</strong></p>
<pre><code>{'ijk': '3', 'abc': '1'}
{'xyzz': '44', 'yew': '55'}
{'wyew': '2232', 'xyz': '8827382'}
</code></pre>
<p>如果您不希望在每个dict中找到匹配项后递归地搜索进一步的匹配项,只需将<code>iterate_dict</code>更改为:</p>
<pre><code>def iterate_dict(d, key, val=None):
if key in d and (val is None or d[key] == val):
yield filter_dict(d, key)
else:
yield from iterate_list(d.values(), key, val)
</code></pre>