第三次是魅力所在...那是你那里有的一些很好的结构:)。在你的评论中你提到你“无法想到更好的树格式来表示这样的数据”...这让我再次冒昧地(稍微)改变输出的格式。为了动态添加子元素,必须创建一个字典来容纳它们。但对于“叶节点”,这个字典永远不会被填充。如果需要,这些当然可以通过另一个循环删除,但在迭代期间不会发生,因为空dict
对于可能的新节点应该存在。有些适用于其中没有文件的节点:这些将包含一个空的list
.
ll = [
{'title': 'Index Page', 'url': 'http://www.example.com/something/index.htm'},
{'title': 'Other Page', 'url': 'http://www.example.com/something/other.htm'},
{'title': 'About Page', 'url': 'http://www.example.com/thatthing/about.htm'},
{'title': 'Detail Page', 'url': 'http://www.example.com/something/thisthing/detail.htm'},
]
# First build a list of all url segments: final item is the title/url dict
paths = []
for item in ll:
split = item['url'].split('/')
paths.append(split[2:-1])
paths[-1].append({'title': item['title'], 'url': split[-1]})
# Loop over these paths, building the format as we go along
root = {}
for path in paths:
branch = root.setdefault(path[0], [{}, []])
for step in path[1:-1]:
branch = branch[0].setdefault(step, [{}, []])
branch[1].append(path[-1])
# As for the cleanup: because of the alternating lists and
# dicts it is a bit more complex, but the following works:
def walker(coll):
if isinstance(coll, list):
for item in coll:
yield item
if isinstance(coll, dict):
for item in coll.itervalues():
yield item
def deleter(coll):
for data in walker(coll):
if data == [] or data == {}:
coll.remove(data)
deleter(data)
deleter(root)
import pprint
pprint.pprint(root)
Output:
{'www.example.com':
[
{'something':
[
{'thisthing':
[
[
{'title': 'Detail Page', 'url': 'detail.htm'}
]
]
},
[
{'title': 'Index Page', 'url': 'index.htm'},
{'title': 'Other Page', 'url': 'other.htm'}
]
],
'thatthing':
[
[
{'title': 'About Page', 'url': 'about.htm'}
]
]
},
]
}