返回路径中的所有项目,包括遍历的每个级别的兄弟姐妹

时间:2013-03-11 22:05:04

标签: python

我甚至不确定如何描述这一点,但我希望有一个人可以理解和帮助。我有许多列表,这些列表包含可能出现在导航结构中的节点的路径,例如:

['nav1']
['nav1','subnav1']
['nav1','subnav2']
['nav2']
['nav3']
['nav3','subnav1']
['nav3','subnav2']
['nav3','subnav3']
['nav3','subnav3','subsubnav1'] **
['nav3','subnav3','subsubnav1','subsubsubnav']
['nav4']
['nav5']
['nav5','subnav1']
['nav5','subnav1','subsubnav1']
['nav5','subnav2']
['nav5','subnav3']

假设我在此导航中选择了**指示的节点,我还想返回作为此节点的父节点和兄弟节点的所有节点。 (与Windows资源管理器树状菜单一样)。

因此,使用所选示例,我将返回:

['nav1']
['nav2']
['nav3']
['nav3','subnav1']
['nav3','subnav2']
['nav3','subnav3']
['nav3','subnav3','subsubitem1']
['nav3','subnav3','subsubitem1','subsubsub']
['nav4']
['nav5']

我想以最有效的pythonic方式实现这一目标。我自己有过几次尝试,但还没有真正成功。这是我最接近的,但不幸的是,它并没有让兄弟姐妹回归。

#model_path is the current selected node e.g ** as illustrated above
#always show 1st level nodes
if len(node_path) == 1:
    return True
#always show final level nodes
if model_path == node_path[:-1]:
    return True
#show all items in tree from root to model
if len(node_path) > 1:
    return self._find_sublist(node_path, model_path) >= 0
#show siblings at each level traversed
#????

# find_sublist credit to this post by nosklo:
# http://stackoverflow.com/a/2251638/1844977
def _find_sublist(self, sub, bigger):
    if not bigger:
        return -1
    if not sub:
        return 0
    first, rest = sub[0], sub[1:]
    pos = 0
    try:
        while True:
            pos = bigger.index(first, pos) + 1
            if not rest or bigger[pos:pos+len(rest)] == rest:
                return pos
    except ValueError:
        return -1

我非常感谢这里的一些帮助,因为我正在努力寻找解决方案。我应该补充说,当有无限数量的级别时,这个解决方案会起作用。

如果这个问题不清楚,或者它是重复的(我担心它可能),我道歉,但事实上,我真的不知道我要问的正确术语对我的搜索没有帮助

顺便说一下,我只限于Python 2.4。

2 个答案:

答案 0 :(得分:3)

以下是我解决问题的方法:

FULL_NAV = [
    ['nav1'],
    ['nav1', 'subnav1'],
    ['nav1', 'subnav2'],
    ['nav2'],
    ['nav3'],
    ['nav3', 'subnav1'],
    ['nav3', 'subnav2'],
    ['nav3', 'subnav3'],
    ['nav3', 'subnav3', 'subsubnav1'],
    ['nav3', 'subnav3', 'subsubnav1', 'subsubsubnav'],
    ['nav4'],
    ['nav5'],
    ['nav5', 'subnav1'],
    ['nav5', 'subnav1', 'subsubnav1'],
    ['nav5', 'subnav2'],
    ['nav5', 'subnav3']
]


def get_required_nav(node_path, full_nav):
    return_list = []

    for comparison_node in full_nav:
        cn_len = len(comparison_node)
        np_len = len(node_path)
        if cn_len <= np_len:
            if comparison_node[:cn_len - 1] == node_path[:cn_len - 1]:
                return_list.append(comparison_node)
        else:
            if comparison_node[:np_len] == node_path:
                return_list.append(comparison_node)

    return return_list


if __name__ == '__main__':
    from pprint import pprint
    pprint(get_required_nav(
        ['nav3', 'subnav3', 'subsubnav1'], FULL_NAV))


# Output of above example:
# [['nav1'],
#  ['nav2'],
#  ['nav3'],
#  ['nav3', 'subnav1'],
#  ['nav3', 'subnav2'],
#  ['nav3', 'subnav3'],
#  ['nav3', 'subnav3', 'subsubnav1'],
#  ['nav3', 'subnav3', 'subsubnav1', 'subsubsubnav'],
#  ['nav4'],
#  ['nav5']]

答案 1 :(得分:-1)

感谢mVChr's answer我能够使用以下内容准确地返回我想要的内容:

FULL_NAV = [
    ['nav1'],
    ['nav1', 'subnav1'],
    ['nav1', 'subnav2'],
    ['nav2'],
    ['nav3'],
    ['nav3', 'subnav1'],
    ['nav3', 'subnav2'],
    ['nav3', 'subnav3'],
    ['nav3', 'subnav3', 'subsubnav1'],
    ['nav3', 'subnav3', 'subsubnav1', 'subsubsubnav'],
    ['nav4'],
    ['nav5'],
    ['nav5', 'subnav1'],
    ['nav5', 'subnav1', 'subsubnav1'],
    ['nav5', 'subnav2'],
    ['nav5', 'subnav3']
]


def get_required_nav(node_path, full_nav):
    return_list = []

    for comparison_node in full_nav:
        cn_len = len(comparison_node)
        np_len = len(node_path)
        if cn_len <= np_len:
            if comparison_node[:cn_len - 1] == node_path[:cn_len - 1]:
                return_list.append(comparison_node)
        else:
            if comparison_node[:-1] == node_path:
                return_list.append(comparison_node)
    return return_list

if __name__ == '__main__':
        from pprint import pprint
        pprint(get_required_nav(
            ['nav3', 'subnav3'], FULL_NAV))


# Output of above example:
# [['nav1'],
#  ['nav2'],
#  ['nav3'],
#  ['nav3', 'subnav1'],
#  ['nav3', 'subnav2'],
#  ['nav3', 'subnav3'],
#  ['nav3', 'subnav3', 'subsubnav1'],
#  ['nav4'],
#  ['nav5']]