在Python中使用嵌套字典我应该检查类型吗?我还可以使用其他什么方法?

Phi*_*hil 4 python python-2.7

免责声明:您好所有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)

我的问题是:

  1. 而不是检查字典中的项的值是否为整数,以查看它是否有子项,我该怎么办?我能做什么?
  2. 什么可能替代这整个事情?(构建数据结构的方式和/或通过它的迭代)

我需要这种url映射方式,因为我的网站可以有很多嵌套部分,我不想多次查询数据库只是为了查看它是否存在.

最后,我感谢你们所有宝贵的时间和建议.

Nik*_* B. 6

而不是检查字典中的项的值是否为整数,以查看它是否有子项,我该怎么办?我能做什么?

问题似乎是你对有孩子的部分和没有孩子的部分使用不同的表示.没有孩子的部分应该只是一个带有空子列表的部分:

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无法匹配,则会抛出一个(这似乎也是合理的).