<p>一种方法是对链接的答案添加一个简单的修改,检查子对象是否已经存在,并使用现有的对象。你知道吗</p>
<pre><code>json_dict = {}
flat_dict = {}
for parent, children in file:
if parent in flat_dict:
value = flat_dict[parent]
else:
value = {}
flat_dict[parent] = json_dict[parent] = value
for child in children:
if child in flat_dict:
value[child] = flat_dict[child]
else:
flat_dict[child] = value[child] = {}
</code></pre>
<p>在这两种情况下,都可以使用<a href="https://docs.python.org/3/library/stdtypes.html#dict.setdefault" rel="nofollow noreferrer">^{<cd1>}</a>来缩短代码,但我通常不会使用它,因为它会创建一个空的dictionary实例,即使这不是必需的:</p>
<pre><code>json_dict = {}
flat_dict = {}
for parent, children in file:
if parent in flat_dict:
value = flat_dict[parent]
else:
value = json_dict[parent] = flat_dict[parent] = {}
for child in children:
value[child] = flat_dict.setdefault(child, {})
</code></pre>
<p>虽然第二个解决方案执行一些可能不必要的操作,但代码看起来确实更加清晰。你知道吗</p>
<p>同样干净但不必要对象较少的另一种方法是使用<a href="https://docs.python.org/3/library/collections.html#collections.defaultdict" rel="nofollow noreferrer">^{<cd2>}</a>:</p>
<pre><code>from collections import defaultdict
json_dict = {}
flat_dict = defaultdict(dict)
for parent, children in file:
if parent in flat_dict:
value = flat_dict[parent]
else:
value = json_dict[parent] = flat_dict[parent]
for child in children:
value[child] = flat_dict[child]
</code></pre>
<p>除了需要导入外,这个解决方案不会像基于<code>dict</code>的常规解决方案那样清晰地打印。但是,这不会以任何方式影响到到到JSON的转换。你知道吗</p>
<p>由于您注释说实际上不希望子节点位于根中,因此此处显示的代码段将仅将父节点放置在根中。但是,如果您稍后发现某个节点是子节点,则它们不会从根节点中删除该节点。这可以通过另一个简单的修改来实现,如<code>defaultdict</code>示例所示,但也适用于所有其他示例:</p>
<pre><code>from collections import defaultdict
json_dict = {}
flat_dict = defaultdict(dict)
for parent, children in file:
if parent in flat_dict:
value = flat_dict[parent]
else:
value = json_dict[parent] = flat_dict[parent]
for child in children:
value[child] = flat_dict[child]
json_dict.pop(child, None)
</code></pre>
<p>这里有一个<a href="http://ideone.com/kmrYxk" rel="nofollow noreferrer">IDEOne link</a>和最后的答案。你知道吗</p>
<p>请记住,此代码不会检查循环引用。循环引用将自动从结果中删除自身。例如:</p>
<pre><code>file = [
('A', ['B']),
('B', ['C']),
('C', ['A']),
]
</code></pre>