如何基于层级URL列表生成嵌套字典?现有代码未达预期求指导
问题:如何为层级URL列表动态生成嵌套字典?
我有一个层级URL列表:
data = ["https://python-rq.org/","https://python-rq.org/a","https://python-rq.org/a/b","https://python-rq.org/c"]
我希望为每个存在子路径的URL条目动态生成嵌套字典,但尝试了以下代码后没有得到预期输出:
import re result = [] for key,d in enumerate(data): form_dict = {} r_pattern = re.search(r"(http(s)?://(.*?)/)(.*)",d) r = r_pattern.group(4) if r == "": parent_url = r_pattern.group(3) else: parent_url = r_pattern.group(3) + "/"+r print(parent_url) temp_list = data.copy() temp_list.pop(key) form_dict["name"] = parent_url form_dict["children"] = [] for t in temp_list: child_dict = {} if parent_url in t: child_dict["name"] = t form_dict["children"].append(child_dict.copy()) result.append(form_dict)
我的预期输出是:
{ "name":"https://python-rq.org/", "children":[ { "name":"https://python-rq.org/a", "children":[ { "name":"https://python-rq.org/a/b", "children":[ ] } ] }, { "name":"https://python-rq.org/c", "children":[ ] } ] }
请问有什么解决建议?
解决方案
先帮你分析下原有代码的问题:
- 你的逻辑是给每个URL单独生成一个顶级字典,最后把所有字典都塞进
result列表,这和你要的单一根节点嵌套结构不符; - 你用
parent_url in t来判断子节点,这会把所有包含当前URL的路径都当成子节点——比如https://python-rq.org/a/b会被同时加到根节点和/a节点的children里,但实际上它只应该是/a的子节点; - 没有处理URL的层级关系,直接平级添加,自然出不来嵌套的效果。
下面给你一个更合理的实现思路和代码:
核心思路
- 先按URL的路径深度排序,确保父URL(路径段更少)先被处理;
- 用一个字典存储每个URL对应的节点,方便快速找到父节点;
- 用URL解析工具准确找到每个URL的直接父URL,把当前节点添加到父节点的children列表中;
- 最后返回最顶层的根节点即可。
完整代码
from urllib.parse import urlparse import json def build_nested_url_dict(urls): # 按URL的路径段数量排序,父节点(路径更短)优先处理 sorted_urls = sorted(urls, key=lambda x: len(urlparse(x).path.strip('/').split('/'))) # 存储每个URL对应的节点,方便快速查找父节点 url_node_map = {} for url in sorted_urls: # 创建当前URL的节点 current_node = {"name": url, "children": []} url_node_map[url] = current_node # 解析URL,获取协议+域名部分,以及路径部分 parsed_url = urlparse(url) base_url = f"{parsed_url.scheme}://{parsed_url.netloc}" path_segments = parsed_url.path.strip('/').split('/') # 找到直接父URL parent_url = None if len(path_segments) > 0 and path_segments[0] != '': # 去掉最后一个路径段,生成父路径 parent_path_segments = path_segments[:-1] if parent_path_segments: parent_path = '/'.join(parent_path_segments) parent_url = f"{base_url}/{parent_path}" else: # 父路径为空,对应根URL parent_url = base_url + '/' # 如果父URL存在于我们的列表中,把当前节点加到父节点的children里 if parent_url and parent_url in url_node_map: url_node_map[parent_url]["children"].append(current_node) # 返回根节点(也就是路径最短的那个URL对应的节点) return next(node for node in url_node_map.values() if len(urlparse(node["name"]).path.strip('/').split('/')) == 0) # 测试运行 data = ["https://python-rq.org/","https://python-rq.org/a","https://python-rq.org/a/b","https://python-rq.org/c"] nested_result = build_nested_url_dict(data) print(json.dumps(nested_result, indent=2))
代码说明
- 排序处理:通过统计路径段的数量排序,保证父节点先被创建,这样处理子节点时父节点已经存在于
url_node_map中; - URL解析:用
urlparse拆分URL的各个部分,能更准确地生成直接父URL,避免手动字符串分割的错误; - 节点映射:用字典存储每个URL对应的节点,查找父节点的时间复杂度是O(1),效率更高;
- 根节点返回:通过判断路径段数量为0找到根URL对应的节点,也就是我们要的顶级嵌套结构。
运行这段代码后,就能得到你想要的嵌套字典输出啦。
内容的提问来源于stack exchange,提问作者user9648966
相关产品推荐
相关产品推荐

