我有一个存储URL的dicts列表.它只有两个字段,title和url.例:
[
{'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'},
]
Run Code Online (Sandbox Code Playgroud)
但是,我要从这个dicts列表中获取树结构.我正在寻找这样的东西:
{ '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'}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
我的第一次尝试是在一堆for循环中的urlparse汤,我相信有更好,更快的方法来做到这一点.
我已经看到人们在SO工作魔法上有列表推导,lambda函数等等.我仍然在搞清楚它.
(对于Django开发人员:我将使用这个我的Django应用程序.我将URL存储在一个模型中,该模型Page有两个字段,name并且title)
第三次是魅力所在...那是你那里有的一些很好的结构:)。在您的评论中,您提到您“无法想到更好的树格式来表示这样的数据” ......这让我再次冒昧地(稍微)改变输出的格式。为了动态添加子元素,必须创建一个字典来容纳它们。但对于“叶节点”,这个字典永远不会被填充。如果需要,这些当然可以通过另一个循环删除,但在迭代期间不会发生,因为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)
Run Code Online (Sandbox Code Playgroud)
输出:
{'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'}
]
]
},
]
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
877 次 |
| 最近记录: |