免责声明:您好所有Python大师和粉丝.我要感谢大家的关心支持和亲切的建议,这对我帮助很大.我是一名Python新手,他正在努力学习和提升,同时牢记最佳实践的重要性.这是一个问题,我正在寻求一种快速的方法来避免类型检查,好像我在这里学到了一件事,这不是一件好事,必须有另一种方法来做.
我正在构建一个数据对象来表示站点地图.我想在内存中这样,所以我可以在查询数据库之前快速映射URL.
每个节点必须有2个元素.一个名称(网站的部分)和ID(它在DB ID)(4至8位正常,但在这里只用一个数字来表示).
如果此节点具有子节点(在页面上),则它具有名称,ID 和表示子节点的另一个字典.
我已经决定使用性能,方便的迭代和内存的原因如下: 我过去只列出[姓名,身份证,[姓名,身份证,..]],字典试过,我觉得这是一个不这样的糟糕的方式.
sitemap = {'section_one': 0,
'section_two': [1, {'c_sect_2_1': 10,
'c_sect_2_2': [11, {'c_sect_2_2_1': 110,
'c_sect_2_2_2': 111,
'c_sect_2_2_3': 112}],
'c_sect_2_3': 12,
'c_sect_2_4': 13}],
'section_three': 2,
'section_four': 3,
'section_five': 4}
Run Code Online (Sandbox Code Playgroud)
我选择了列表,因为我可能需要修改它们(因此没有元组) 我正在使用字典(hashable),我可以轻松检查它们是否包含一个部分.
使用这种数据集,下面的功能,我映射URL(例如/ section_two/c_sect_2_2/c_sect_2_2_3),看看它的存在与否来从数据库中的数据.我的功能:
def map_url(url): #url here is a list e.g. ['section_two', 'c_sect_2_2', 'c_sect_2_2_3']
sm = sitemap
for e in url:
if e in sm:
if isinstance(sm[e], int):
return sm[e] #e = where it stops matching due to no children
sm = sm[e][1] #if not INT it's a list. list[1] has another dict to go-through
return False #the URL could not be matched-mapped
Run Code Online (Sandbox Code Playgroud)
我的问题是:
我需要这种url映射方式,因为我的网站可以有很多嵌套部分,我不想多次查询数据库只是为了查看它是否存在.
最后,我感谢你们所有宝贵的时间和建议.
而不是检查字典中的项的值是否为整数,以查看它是否有子项,我该怎么办?我能做什么?
问题似乎是你对有孩子的部分和没有孩子的部分使用不同的表示.没有孩子的部分应该只是一个带有空子列表的部分:
sitemap = {'section_one': [0, {}],
'section_two': [1, {'c_sect_2_1': [10, {}],
'c_sect_2_2': [11, {'c_sect_2_2_1': [110, {}],
'c_sect_2_2_2': [111, {}],
'c_sect_2_2_3': [112, {}]}],
'c_sect_2_3': [12, {}],
'c_sect_2_4': [13, {}]}],
'section_three': [2, {}],
'section_four': [3, {}],
'section_five': [4, {}]}
Run Code Online (Sandbox Code Playgroud)
现在你的代码应该变得更简单了.
什么可能替代这整个事情?(构建数据结构的方式和/或通过它的迭代)
您可以在程序开始时将站点地图转换为平面词典,这样就可以了
flat_sitemap = {
'section_one': 0,
'section_two': 1,
'section_two/c_sect_2_1': 10,
# ...
'section_two/c_sect_2_2/c_sect_2_2_1': 110
# ...
}
Run Code Online (Sandbox Code Playgroud)
这样,您的查询将在预期的O(1)时间内以更高的空间使用量为代价.
至于以不同方式处理原始结构,可以使用递归.我经常发现以递归方式在树状结构上制定算法更容易,但这取决于你的思维方式.这是一个例子(我假设sitemap我的第一个样本中显示了它的格式):
def map_url(url, sm=[None, sitemap]):
if not url: return sm[0]
if url[0] not in sm[1]: return False
return map_url(url[1:], sm[1][url[0]])
print map_url(['section_two', 'c_sect_2_2', 'c_sect_2_2_3']) # => 112
print map_url(['section_two', 'c_sect_2_2']) # => 10
print map_url(['section_two', 'notexisting']) # => False
print map_url([]) # => None
Run Code Online (Sandbox Code Playgroud)
如您所见,这使得特殊情况显式传递空URL.你应该考虑在那个特定情况下会发生什么.
你甚至可以离开功能的第二行.在这种情况下,KeyError如果URL无法匹配,则会抛出一个(这似乎也是合理的).