Ссылки на занятия по питону на себя - PullRequest
0 голосов
/ 04 октября 2011

Я полагаю, что этот код должен выводить:

8
8

, но это не так.

class tree:
    def __init__(self, size=2):
        if size == 0:
            return None
        if size > 1:
            half = size//2
            self.left = tree(size-half)
            self.right = tree(half)
        else:
            self.left = self.right = None
        self.free = size
        self.size = size

    def resize(self,n):
        while self.size < n:
            t = tree(0)
            t.left = self
            t.right = tree(self.size)
            t.free = t.left.size + t.right.size
            t.size = self.size * 2
            self = t
        print("size in resize", self.size)

t = tree()
t.resize(5)
print("size of t", t.size)

вывод:

size in resize 8
size of t 2

Я знаю, что мог бы сделать return self в resize и t = tree.resize(5) в основном, но что, если я хочу вернуть что-то еще?

Ответы [ 2 ]

4 голосов
/ 04 октября 2011

Ответ Карла абсолютно верен во всем, но, безусловно, есть способ заставить resize действовать так, как вы ожидаете.

Три шага:

  1. Сделать копиюдерева
  2. Повторно инициализируйте дерево, чтобы оно стало на следующий размер больше
  3. Установите увеличенное дерево left на копию исходного дерева

    def resize(self,n):
            while self.size < n:
                new = self.copy()
                self.__init__(int(round(self.size, 2)) * 2)
                self.left = new
    
            print("size in resize",self.size)
    
    def copy(self):
            new = tree(1)
            new.left = self.left
            new.right = self.right
            new.size = self.size
            new.free = self.free
            return new
    

По сути, вы пытались сделать это задом наперед - замените self и повторно используйте self для self.left вместо замены self.left и повторного использования self.

2 голосов
/ 04 октября 2011

self = t

Это не так, и нельзя переписать в , делайте что хотите.В имени Python нет ничего «особенного» в названии self;это как любая другая переменная (тот факт, что вы должны передать ее явно методам, должен был стать вашей первой подсказкой, в отличие от языков, которые рассматривают this как ключевое слово, должен был стать вашей первой подсказкой;)), и, как и вседругие переменные, он имеет ссылочную семантику.

self = t означает «с этой точки и далее (до другого переопределения или до конца области действия), self больше не ссылается на то, к чему относится этот параметр selfв, но вместо значения, на которое t ссылается ".

Кроме того, у вас есть опечатка в одном случае вашего __init__ метода ('rigt'), и я предполагаю, что число free узлы должны быть инвариантами чего-то вроде size - occupied;в этом случае было бы чётче подсчитывать занятые узлы и использовать метод или свойство для вычисления свободных, вместо того, чтобы пытаться обновлять это число при каждой модификации.

(Более того, что вы, похоже, пытаетесьделать это все виды непифоновых. В частности, идея контейнера, имеющего определенный «выделенный размер», странная, такого рода вещи обычно имеют значение только на стороне C. Забора, что вам нужно двоичное деревоfor? Кроме того, этот метод вообще не собирается уравновешивать дерево. И зачем использовать дерево, если ни один из узлов не хранит какие-либо данные?)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...