Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中列表的递归排序函数_Python_Recursion_Nested Loops_Python 2.6_Nested Lists - Fatal编程技术网

Python中列表的递归排序函数

Python中列表的递归排序函数,python,recursion,nested-loops,python-2.6,nested-lists,Python,Recursion,Nested Loops,Python 2.6,Nested Lists,我想列举如下: groups = ["foo", "bar", "foo::fone", "foo::ftwo", "foo::ftwo::ffone"] 并将其转换为嵌套列表,可能采用以下格式,但我愿意接受建议: groups_sorted = [{ "name":"foo", "children": [ {

我想列举如下:

groups = ["foo", "bar", "foo::fone", "foo::ftwo", "foo::ftwo::ffone"]
并将其转换为嵌套列表,可能采用以下格式,但我愿意接受建议:

groups_sorted = [{
                    "name":"foo",
                    "children": [
                                  {
                                    "name": "foo::fone",
                                    "children": [ ... ]
                                  }, ...
                                ]
                 }, ...
                ]
因此,使用
上的层次结构拆分对列表进行排序。我需要将每个
子项
键本身作为列表,因为列表的原始顺序很重要

我已经玩了几个小时,能够从一个顶部节点开始创建递归字典,但最后一点我做不到。在下面找到我的工作:

def children_of(node, candidates):
    children = []
    remainder = []
    for c in candidates:
        sub = node + "::"
        if c.startswith(sub):
            try:
                c[len(sub):].index("::") # any more separators = not a child
                remainder.append(c)
            except ValueError: # a child
                children.append(c)    
        else: #not related
            remainder.append(c)
    return children, remainder

def sortit(l):
    if l:
        el = l.pop(0)
        children, remainder = children_of(el,l)
        if children:    
            return { "name": el,
                     "children": [sortit([c]+remainder) for c in children]
                   }
        else:
            return { "name": el }

编辑:@Thijs van Dien的解决方案非常好,但我需要2.6兼容性,这阻止我使用OrderDicts

换成这样怎么样

from collections import OrderedDict

dic = OrderedDict()

def insert(name):
    current_dic = dic
    current_name = ''
    for name_elem in name.split('::'):
        current_name += ('::' if current_name else '') + name_elem
        if not current_name in current_dic:
            current_dic[current_name] = OrderedDict()
        current_dic = current_dic[current_name]

for group in ["foo", "bar", "foo::fone", "foo::ftwo", "foo::ftwo::ffone"]:
    insert(group)
这将为您提供以下结构:

{'bar': {}, 'foo': {'foo::fone': {}, 'foo::ftwo': {'foo::ftwo::ffone': {}}}}
OrderedDict
确保保留订单,因此您不需要使用任何
列表。此外,您不需要使用递归,因为Python中不建议使用递归

如果标准库中没有
OrderedDict
,因为您使用的是Python 2.6,那么可以安装它:

pip install ordereddict
然后更改导入:

from ordereddict import OrderedDict
这里有另一个解决方案,只有在你需要父母的时候,你才能假设他们已经存在。如果您有重复的组,情况会变糟,因此您需要自己进行调整

children_of_name = dict([('', list())]) # Access root with empty string

def insert(name):
    parent_name = '::'.join(name.split('::')[:-1])
    dic = dict([('name', name), ('children', list())])
    children_of_name[parent_name].append(dic)
    children_of_name[name] = dic['children']

for group in ["foo", "bar", "foo::fone", "foo::ftwo", "foo::ftwo::ffone"]:
    insert(group)
它为您提供了您建议的结构:

[{'children': [{'children': [], 'name': 'foo::fone'},
               {'children': [{'children': [], 'name': 'foo::ftwo::ffone'}],
                'name': 'foo::ftwo'}],
  'name': 'foo'},
 {'children': [], 'name': 'bar'}]

谢谢-很抱歉,这是一个非常好的答案,但我不能使用OrderedPicts,因为我们使用的是Python 2。6@IanClark请,请在作业中列出这些要求。。。但是,您仍然可以查找OrderedDict配方;您不需要从标准库中获取它。@IanClark添加了获取
订单信息的说明。
。谢谢-不幸的是,我无法访问服务器,因此我需要坚持使用标准2.6library@IanClark最后一个选项是手动粘贴此配方:。我认为没有必要重新发明它。平方时间复杂度,你在说什么?上述代码与元素数量呈线性关系。您可能只会在非常深的嵌套中遇到问题,因为它总是从顶部向下移动(尽管有恒定的时间查找)。你可以更明智地避免这种情况。想一想父级已经存在的某种二进制搜索。