【问题标题】:Python output a list in hierarchy [duplicate]Python在层次结构中输出列表[重复]
【发布时间】:2022-01-26 03:17:19
【问题描述】:

我一直在尝试为下面的代码示例编写一个递归函数,但我面临的问题是我的循环在下次运行时会翻倍。


def get_choices():
    choices = []
    nodes = Node.query.filter_by(parent_id=None).all()
    for node in nodes:
        choices.append((node.id, f"{node.value}"))
        if node.children:
            for child in node.children:
                choices.append((child.id, f"-{child.value}"))
                if child.children:
                    for c in child.children:
                        choices.append((c.id, f"--{c.value}"))

    return choices

我目前正在处理的代码


def get_choices():
    c = Node.query.filter_by(parent_id=None).all()

    return _get_choices(c)

def _get_choices(children, depth=0, prev_choices=[]):

    new_choices = prev_choices
    for child in children:
        new_choices.append((child.id, f"{depth * '-'}{child.value}"))
        if child.children:
            _get_choices(child.children, depth+1, new_choices)
    
    return new_choices

【问题讨论】:

  • 非常感谢,它帮助我解决了我的问题。

标签: python recursion tree


【解决方案1】:

我想你打算这样做:

def _get_choices(nodes, depth=0):
    if not nodes:
        return []
    for node in nodes:
        yield (node.id, f"{depth * '-'}{node.value}")
        yield from _get_choices(node.children, depth+1)


def get_choices():
    return list(_get_choices(Node.query.filter_by(parent_id=None).all()))

我不知道在Node 中会发生什么,但如果我对您的数据结构的理解是正确的,这将为每个节点及其每个子节点生成一个元组,一直向下,深度优先。

顺便说一句:使用内置函数或关键字的名称作为变量或属性名称通常不是一个好主意。它工作得很好,但你可能想重命名id(这是一个内置函数)。

由于我没有要测试的数据,所以这里有一个对样本数据执行相同操作的示例:

class Node:
    def __init__(self, ident, value, children=None):
        self.ident = ident
        self.value = value
        self.children = children if children else []


data = [
    Node(1, 'a', [Node(2, 'b'), Node(3, 'c', [Node(4, 'd')])]),
    Node(5, 'e', [Node(6, 'f'), Node(7, 'g'), Node(8, 'h')]),
    Node(9, 'i')
]


def _get_choices(nodes, depth=0):
    if not nodes:
        return []
    for node in nodes:
        yield (node.ident, f"{depth * '-'}{node.value}")
        yield from _get_choices(node.children, depth+1)


def get_choices():
    return list(_get_choices(data))


print(result := get_choices())
for __, x in result:
    print(x)

结果:

[(1, 'a'), (2, '-b'), (3, '-c'), (4, '--d'), (5, 'e'), (6, '-f'), (7, '-g'), (8, '-h'), (9, 'i')]
a
-b
-c
--d
e
-f
-g
-h
i

【讨论】:

  • 看起来很整洁,正是我想要的。生病把它插入我的代码,看看它是怎么回事。谢谢。今天学习一些新东西,以前从未见过的收益:)
  • 你知道这是否更快,或者有办法编写一个 sql 模式来过滤相同的结果。
  • 嗯,总是有一种很好的迭代方式来重写递归函数,但它并不总是更快,而且肯定更不容易阅读。然而,递归确实有相当大的开销。您也可以编写递归 SQL 查询,但需要做一些工作——这可能是最快的,但也是最复杂的。您的代码的其他更改可能会更重要,速度更快
  • 如果这个答案(或另一个)确实回答了您的问题,请在旁边打勾接受它,这样问题就不会再出现未回答(您仍然可以根据需要发布 cmets 或进行更改)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-04
  • 1970-01-01
相关资源
最近更新 更多