Рекурсивный перебор узлов, на которые ссылаются другие узлы

#python #object #object-reference

#python #объект #ссылка на объект #объект-ссылка

Вопрос:

Как я мог рекурсивно перебирать узлы со ссылкой на предыдущий узел? Ожидаемый результат 4,3,2,1 в примере ниже:

 class Node:
    def __init__(self, parent, value):
        self.parent = parent
        self.value = value

    def append(self, value):
        return Node(self, value)

def list(l):
    print(l.value)
    while l.parent is not None:
        list(l.parent)

l = Node(None, 1)
l = l.append(2)
l = l.append(3)
l = l.append(4)
list(l)
  

Комментарии:

1. на первый взгляд это выглядит многообещающе. Что это дает вам, когда вы его запускаете? (На данный момент я не могу протестировать скрипт на Python.)

2. Вы можете использовать self для передачи текущего объекта другому. Например: self.child.parent = self является допустимым фрагментом кода (хотя в вашем коде нет дочернего атрибута, я думаю, это может ответить на ваш вопрос)

3. @RobinZigmond на данный момент он рекурсивно выдает мне ‘1’ с

Ответ №1:

Ваша структура класса уже успешно передает self значение узла его дочернему узлу. Проблема в вашей list функции. while l.parent is not None: никогда не заканчивается, потому что ничто в цикле не изменяет значение l . list Рекурсивный вызов создаст новый контекст, в котором другая переменная с именем l имеет значение, отличное от значения первого контекста l , но это никак не влияет на первый l цикл. Рекурсивные функции обычно не требуют фактического цикла для перебора элементов структуры данных. Попробуйте:

 def list(l):
    print(l.value)
    if l.parent is not None:
        list(l.parent)
  

Или:

 def list(l):
    while l is not None:
        print(l.value)
        l = l.parent
  

(Я рекомендую последнее, потому что первое приведет к сбою с «превышением максимальной глубины рекурсии», если цепочка содержит более 999 элементов)

Результат:

 4
3
2
1
  

Бонусный совет по стилю: подумайте о том, чтобы назвать свою функцию как-нибудь иначе, чем list . В общем, вам следует избегать перезаписи имен встроенных функций и типов.

Комментарии:

1. Причина № 1, по которой следует избегать рекурсии здесь, заключается в том, что рекурсия имеет гораздо более высокую стоимость, чем итерация (примечание: вы можете настроить максимальную глубину рекурсии).

Ответ №2:

Я должен проголосовать за закрытие вашего вопроса из-за отсутствия четкой постановки проблемы, но в любом случае…

Внутри объекта в Python, как я могу передать ссылку на мой текущий объект

Так же, как вы бы поступили с любым объектом.

к объекту b того же класса

На самом деле это не имеет значения, но в любом случае…

таким образом, что когда я вызываю b.parent, я могу вернуться к объекту a?

 class Foo(object):
    def __init__(self, parent=None):
        self.parent = parent

a = Foo()
b = Foo(a)
print(b.parent is a)
  

Теперь для ответа на вопрос, который вы не задавали, посмотрите (и примите) ответ Кевина 😉