#python #recursion #directed-acyclic-graphs
#python #рекурсия #directed-acyclic-graphs
Вопрос:
Есть график, отображающий типы классов в список их аргументов. Как мне вернуть корни, созданные с их предками для аргументов? (Извиняюсь за то, что, вероятно, является ужасным описанием моей проблемы). Рассмотрим следующее:
graph = {Foo: [42], Baz: [None], Bar: [Baz], FooBar: [Foo, Bar], Qux: [True]}
Для корней, возвращаемых set(graph).difference(chain.from_iterable(graph.values()))
, я ожидаю два значения, qux
и foobar
, созданные следующим образом:
qux = Qux(True)
foobar = FooBar(Foo(42), Bar(Baz(None)))
Вот дополнительный код для воспроизведения примера:
from itertools import chain
class Node:
name = None
def __init__(self, *args):
self.args = args
class FooBar(Node):
name = 'foobar'
class Foo(Node):
name = 'foo'
parent = FooBar
class Bar(Node):
name = 'bar'
parent = FooBar
class Baz(Node):
name = 'baz'
parent = Bar
class Qux(Node):
name = 'qux'
Заранее благодарю.
Комментарии:
1. Вы хотите создать отдельный класс для каждого экземпляра? Это не то, для чего нужны классы!
2. Это имеет место в этом упрощенном примере.
3. Я предлагаю изменить ваш код, чтобы создать другой объект того же класса для каждого экземпляра. Не создавайте отдельный класс для каждого узла вашего графика.
4. Спасибо, хотя в реальном приложении эти классы имитируют широко используются / повторно используются. Опять же, это упрощенный пример.
Ответ №1:
Вы могли бы использовать эту рекурсивную функцию:
def get_inst (graph, arg):
val = graph[arg]
return arg(*(el if type(el) != type else get_inst (graph, el) for el in val))
Пример использования этой функции:
roots = set(graph).difference(chain.from_iterable(graph.values()))
for root in roots:
val = get_inst(graph, root)
Комментарии:
1. Отличное решение. Спасибо.