Страницы

Поиск по вопросам

пятница, 24 января 2020 г.

Python - NameError (двунаправленный связный список)

#python #двусвязный_список


Правильно ли я реализую двунаправленный связный список и, если да, то как исправить
ошибку?

class Cell:
    def __init__(self, value, name, prev, next):
        self.value = value
        self.name = name
        self.prev = prev
        self.next = next

E = Cell(5, "E", D, None)
D = Cell(4, "D", C, E)
C = Cell(3, "C", B, D)
B = Cell(2, "B", A, C)
A = Cell(1, "A", None, B)



  NameError: name 'D' is not defined

    


Ответы

Ответ 1



Вы на правильном пути, однако если конструктор списка будет принимать и предыдущую и следующую вершины, то возникнет циклическая зависимость. Возможным решением может быть убирание prev и next из конструктора и вынос их установки в отдельный метод: class Cell: def __init__(self, value, name): self.value = value self.name = name def set_prev_and_next(self, prev, next): self.prev = prev self.next = next A = Cell(1, 'A') B = Cell(2, 'B') C = Cell(3, 'C') D = Cell(4, 'D') E = Cell(5, 'E') A.set_prev_and_next(E, B) B.set_prev_and_next(A, C) C.set_prev_and_next(B, D) D.set_prev_and_next(C, E) E.set_prev_and_next(D, A) Однако в таком случае вам нужно будет каждый раз ручками заботиться о том, чтобы значения prev и next были согласованы. Например, если вы захотите вставить элемент в середину списка, то вам нужно будет вызвать метод set_prev_and_next у трёх элементов: вставляемого, предыдущего и следующего. Гораздо лучшим вариантом будет написать метод вроде insert_after, который будет вставлять элемент после некоторого элемента и сам обрабатывать согласованность значений prev и next. Например, так: class Cell: def __init__(self, value, name): self.value = value self.name = name self.prev = None self.next = None def insert_after(self, cell): if self.next is None: cell.prev = self cell.next = self self.prev = cell self.next = cell else: cell.prev = self cell.next = self.next self.next = next cell.next.prev = cell A = Cell(1, 'A') B = Cell(2, 'B') C = Cell(3, 'C') D = Cell(4, 'D') E = Cell(5, 'E') B.insert_after(A) C.insert_after(B) D.insert_after(C) E.insert_after(D)

Ответ 2



У Вас не получится вызвать переменную до ее определения, необходимо изменить порядок,чтобы интерпретатор знал куда вы обращаетесь, так работать не будет E = Cell(5, "E", D, None) D = Cell(4, "D", C, E) C = Cell(3, "C", B, D) B = Cell(2, "B", A, C) A = Cell(1, "A", None, B) можно попробовать изменить логику, я могу ошибаться и буду благадарен за правки более опытных участников class Constr(object): def __init__(self, value, name, prev=None): self.value = value self.name = name self.prev = prev self.next = None def add_next(self, obj): self.next = obj def show(self): answer = dict(name=self.name, value=self.value, prev=self.prev, next=self.next) return answer class Contain(object): def __init__(self): self.all_obj = [] def update_obj(self, value, name): if not self.all_obj: new = Constr(value, name) self.all_obj.append(new) else: update_obj = self.all_obj[-1] new_obj = Constr(value, name, prev=update_obj) update_obj.add_next(new_obj) self.all_obj.append(new_obj) return True def get_list(self): if self.all_obj: return [i.show() or None for i in self.all_obj] return [] test = Contain() test.update_obj(1, 'hello') test.update_obj(2, 'world') test.update_obj(3, '!') test.get_list()

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

Отправить комментарий