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最后一个选项是手动粘贴此配方:。我认为没有必要重新发明它。平方时间复杂度,你在说什么?上述代码与元素数量呈线性关系。您可能只会在非常深的嵌套中遇到问题,因为它总是从顶部向下移动(尽管有恒定的时间查找)。你可以更明智地避免这种情况。想一想父级已经存在的某种二进制搜索。