<p>我是在看到@VoNWooDSoN的答案后写的。我把它变成了一个迭代器,而不是在函数内部打印,并做了一些修改,使它更具可读性。所以在这里看他的<a href="https://stackoverflow.com/a/68490869/13944524">original answer</a></p>
<pre><code>def flatten(d, base=()):
for k, v in d.items():
if isinstance(v, dict):
yield from flatten(v, base + (k,))
else:
yield base + (k, v)
</code></pre>
<p>1-生产而不是印刷</p>
<p>2-<code>isinstance()</code>而不是<code>type</code>,因此<code>dict</code>的子类也可以工作。您还可以使用来自<code>typing</code>模块的<code>MutableMapping</code>而不是<code>dict</code>使其更通用</p>
<p>3-IMO,从<code>.items()</code>获取<code>(k, v)</code>对比<code>k</code>和<code>d[k]</code>可读性强得多</p>
<h2 id="more-generic">更通用</h2>
<p>你想把它扩展到更一般的<strong>可以<strong>接受<code>depths</code>的数字以防万一吗</p>
考虑这些例子:</P>
<pre><code>d_level1 = {"a": 1, "b": 2, "c": 3}
d_level2 = {"group_1": {"a": 1}, "group_2": {"b": 2, "c": 3}}
d_level3 = {"collection_1": d_level2}
for items in flatten(d_level3):
print(items)
print('------------------------------')
for items in flatten(d_level3, depth=0):
print(items)
print('------------------------------')
for items in flatten(d_level3, depth=1):
print(items)
print('------------------------------')
for items in flatten(d_level3, depth=2):
print(items)
</code></pre>
<p>输出:</p>
<pre><code>('collection_1', 'group_1', 'a', 1)
('collection_1', 'group_2', 'b', 2)
('collection_1', 'group_2', 'c', 3)
------------------------------
('collection_1', {'group_1': {'a': 1}, 'group_2': {'b': 2, 'c': 3}})
------------------------------
('collection_1', 'group_1', {'a': 1})
('collection_1', 'group_2', {'b': 2, 'c': 3})
------------------------------
('collection_1', 'group_1', 'a', 1)
('collection_1', 'group_2', 'b', 2)
('collection_1', 'group_2', 'c', 3)
</code></pre>
<P>^ <CD12>}不考虑深度(仍然像你希望的那样在第一位置工作)。但是现在通过指定从<code>0</code>到<code>2</code>的深度,您可以看到我们可以迭代我们想要的深度。代码如下:</p>
<pre><code>def flatten(d, base=(), depth=None):
for k, v in d.items():
if not isinstance(v, dict):
yield base + (k, v)
else:
if depth is None:
yield from flatten(v, base + (k,))
else:
if depth == 0:
yield base + (k, v)
else:
yield from flatten(v, base + (k,), depth - 1)
</code></pre>