One-line Tree in Python
环境:Windows, sublime text, python 2.7
one-line tree in python · GitHub https://gist.github.com/hrldcpr/2012250
One-line Tree In Python | Hacker News https://news.ycombinator.com/item?id=3881171
python自带的库里提供defaultdict
from collections import defaultdict
def tree(): return defaultdict(tree)
def dicts(t):
return {k: dicts(t[k]) for k in t}
def dicts1(t):
'''
recurssion to handle sub-dict
'''
dic = {}
for k in t:
dic[k] = dicts(t[k])
return dic
第二个是第一个的详细版本,两个函数一样的。
递归把defaultdict对象转为dict对象。这里理解的关键在于一开始递归的时候整个是一个字典,字典包一层字典,和洋葱一样(此时应有BGM我一层一层剥开你的心。。。)把defaultdict对象转为dict对象。
举例子。在最底层的递归情况,传入一个{ }字典,不进入for。在中间递归层,传入{'a1': { }, 'a2': { } },for跑两次,这两次底层不进入for返回。
taxonomy = tree()
taxonomy['Animalia']['Chordata']['Mammalia']['Carnivora']['Felidae']['Felis']['cat']
taxonomy['Animalia']['Chordata']['Mammalia']['Carnivora']['Felidae']['Panthera']['lion']
taxonomy['Animalia']['Chordata']['Mammalia']['Carnivora']['Canidae']['Canis']['dog']
taxonomy['Animalia']['Chordata']['Mammalia']['Carnivora']['Canidae']['Canis']['coyote']
taxonomy['Plantae']['Solanales']['Solanaceae']['Solanum']['tomato']
taxonomy['Plantae']['Solanales']['Solanaceae']['Solanum']['potato']
taxonomy['Plantae']['Solanales']['Convolvulaceae']['Ipomoea']['sweet potato']
import pprint
pp = pprint.PrettyPrinter(indent=8)
pp.pprint(dicts1(taxonomy))
这样是pretty print,数据结构更清楚。
输出:
{ 'Animalia': { 'Chordata': { 'Mammalia': { 'Carnivora': { 'Canidae': { 'Canis': { 'coyote': { },
'dog': { }}},
'Felidae': { 'Felis': { 'cat': { }},
'Panthera': { 'lion': { }}}}}}},
'Plantae': { 'Solanales': { 'Convolvulaceae': { 'Ipomoea': { 'sweet potato': { }}},
'Solanaceae': { 'Solanum': { 'potato': { },
'tomato': { }}}}}}
def add(t, path):
for node in path:
t = t[node]
add方法。
add(taxonomy, 'Animalia>Chordata>Mammalia>Cetacea>Balaenopteridae>Balaenoptera>blue whale'.split('>'))
在对list的for循环中,逐级抵达底层叶子节点。注意在整个过程中只引用(referencing),不分配(no assigning)
网上评论:Autovivification,该特性最早出现在Perl中,指的是在某个数组被引用时自动创建该数组。Python本身是不支持该特性的,但可以通过本文所述的defaultdict模仿。