Python列表的递归增加了额外的嵌套

时间:2017-01-24 04:46:01

标签: python recursion nested-lists

我正在尝试解决与此处列出的问题类似的问题:Python: Combinations of parent-child hierarchy

graph = {}

nodes = [
('top','1a'),
('top','1a1'),
('top','1b'),
('top','1c'),
('1a','2a'),
('1b','2b'),
('1c','2c'),
('2a','3a'),
('2c','3c'),
('3c','4c')
]

for parent,child in nodes:
    graph.setdefault(parent,[]).append(child)

def find_all_paths(graph, start, path=[]):
    path = path + [start]

    if not graph.has_key(start):
        return path

    paths = []

    for node in graph[start]:
        paths.append(find_all_paths(graph, node, path))

    return paths

test = find_all_paths(graph, 'top')

期望的输出:

[['top', '1a', '2a', '3a'],
 ['top', '1a1'],
 ['top', '1b', '2b'],
 ['top', '1c', '2c', '3c', '4c']]

实际输出:

[[[['top', '1a', '2a', '3a']]],
 ['top', '1a1'],
 [['top', '1b', '2b']],
 [[[['top', '1c', '2c', '3c', '4c']]]]]

有关如何删除额外嵌套的任何建议?谢谢!

3 个答案:

答案 0 :(得分:4)

以下内容应解决您的问题:

//object I need to use to construct requests
var batches = [of_objects];
var sequence = Promise.resolve();
var self = this;

batches.forEach(function(batch){
    sequence
    //Function returns promise
    .then( function(){
        return self._createRequestPromise(batch); //this runs first 5x
    })
    //callback so we can update, returns nothing
    .then(callback)
    //add 3 sec timeout before next request
    .then(function(){
        return new Promise(function (resolve, reject){
            setTimeout(resolve, 3000); //this runs after 5x
        });
    });
});
return sequence;

答案 1 :(得分:3)

问题是path(单个列表)和paths(列表列表)之间的混淆。您的函数可以返回任一个,具体取决于您在图表中的位置。

您可能希望在所有情况下都返回路径列表。因此,请将基本案例中的return path更改为return [path]

在递归的情况下,您现在需要处理将每个孩子的路径合并在一起。我建议使用paths.extend(...)代替paths.append(...)

总而言之,你得到:

def find_all_paths(graph, start, path=[]):
    path = path + [start]

    if not graph.has_key(start):
        return [path]

    paths = []

    for node in graph[start]:
        paths.extend(find_all_paths(graph, node, path))

    return paths

答案 2 :(得分:0)

这是一种非递归解决方案。然而,它"作弊"通过对输出列表进行排序。

def find_all_paths(edges):
    graph = {}
    for u, v in edges:
        if u in graph:
            graph[v] = graph[u] + [v]
            del graph[u]
        else:
            graph[v] = [u, v]
    return sorted(graph.values())

data = (
    ('top','1a'),
    ('top','1a1'),
    ('top','1b'),
    ('top','1c'),
    ('1a','2a'),
    ('1b','2b'),
    ('1c','2c'),
    ('2a','3a'),
    ('2c','3c'),
    ('3c','4c'),
)

test = find_all_paths(data)
for row in test:
    print(row)

<强>输出

['top', '1a', '2a', '3a']                                                                                                                      
['top', '1a1']                                                                                                                                 
['top', '1b', '2b']                                                                                                                            
['top', '1c', '2c', '3c', '4c']