Ошибка типа рекурсии списка Python

Решено: проблема возникает только с PythonWin. Я прогнал все через оболочку Python IDLE, и все заработало. Должна быть ошибка в PythonWin, а не в самом коде.

Я не могу понять, почему следующий код дает мне TypeError: 'type' object is not iterable

pastebin: http://pastebin.com/VFZYY4v0

def genList(self):
    #recursively generates a sorted list of child node values
    numList = []
    if self.leftChild != 'none':
        numList.extend(self.leftChild.genList())  #error
    numList.extend(list((self.Value,)))
    if self.rightChild != 'none':
        numList.extend(self.rightChild.genList()) #error
    return numList

код, добавляющий дочерние узлы (работает корректно)

def addChild(self, child):
    #add a child node. working
    if child.Value < self.Value:
        if self.leftChild == 'none':
            self.leftChild = child
            child.parent = self
        else:
            self.leftChild.addChild(child)
    elif child.Value > self.Value:
        if self.rightChild == 'none':
            self.rightChild = child
            child.parent = self
        else:
            self.rightChild.addChild(child)

Любая помощь будет оценена по достоинству.

Полный сеанс интерпретатора: ››› импортировать BinTreeNode как BTN
››› node1 = BTN.BinaryTreeNode(5)
››› node2 = BTN.BinaryTreeNode(2)
››› node3 = BTN.BinaryTreeNode(12)
››› node3 = BTN.BinaryTreeNode(16)
››› node4 = BTN.BinaryTreeNode(4)
››› node5 = BTN.BinaryTreeNode(13 )
››› node1.addChild(node2)
››› node1.addChild(node3)
››› node1.addChild(node4)
››› node1.addChild (node5)
››› node4.genList()
‹class 'list'›
››› node1.genList()
Traceback (последний последний вызов):< br /> Файл "‹interactive input›", строка 1, в ‹module›
Файл "C:...\python\BinTreeNode.py", строка 47, в genList
numList.extend( self.leftChild.genList()) #error
Файл "C:...\python\BinTreeNode.py", строка 52, в genList
TypeError: 'type' object is not iterable
>


person Jacob J Callahan    schedule 01.12.2012    source источник
comment
Можете ли вы опубликовать всю ошибку? Или больше кода. Как генерируются leftChild и rightChild?   -  person jgritty    schedule 01.12.2012
comment
@JacobJCallahan: Пожалуйста, обновите свой вопрос, указав всю необходимую информацию.   -  person jdi    schedule 01.12.2012
comment
вот полная ошибка: Traceback (последний последний вызов): Файл ‹interactive input›, строка 1, в ‹module› Файл C:\...\python\BinTreeNode.py, строка 47, в genList numList.extend( self.leftChild.genList()) #error Файл C:\...\python\BinTreeNode.py, строка 52, в genList TypeError: объект 'type' не повторяется   -  person Jacob J Callahan    schedule 01.12.2012
comment
@JacobJCallahan не публикуйте информацию в комментариях, если вы не можете ее правильно отформатировать. Отредактируйте свой вопрос.   -  person Mark Reed    schedule 01.12.2012
comment
спасибо, Марк. новое на этом сайте.   -  person Jacob J Callahan    schedule 01.12.2012
comment
Из предоставленного вами кода кажется, что numList.extend() всегда будет получать экземпляр списка. У меня такое чувство, что это можно решить, только увидев весь код: -/   -  person jdi    schedule 01.12.2012
comment
@jdi в этом смысл этой функции. в основном для возврата отсортированного списка из двоичного дерева. я бы вызвал функцию из верхнего узла, и она будет рекурсивно генерировать отсортированный список.   -  person Jacob J Callahan    schedule 01.12.2012
comment
numList.extend(list((self.Value,))) кажется, что это должно быть просто numList.append(self.Value) ... (это не ваша проблема, но это было бы менее запутанно) -- Вы случайно не затенили встроенный list, не так ли?   -  person mgilson    schedule 01.12.2012
comment
@mgilson, который на самом деле вернул бы int и имел бы аналогичную ошибку. TypeError: 'type' int не повторяется   -  person Jacob J Callahan    schedule 01.12.2012
comment
@JacobJCallahan: Это не кажется правильным. Что-то здесь не так.   -  person jdi    schedule 01.12.2012
comment
Думаю опубликовать весь BinTreeNode.py   -  person jgritty    schedule 01.12.2012
comment
@JacobJCallahan - Нет, он вернет список с 1 элементом. Как бы то ни было, вы создаете кортеж из 1 элемента, преобразуете его в список, а затем используете его для расширения имеющегося списка. Это то же самое, что добавить 1 элемент в список, который у вас есть.   -  person mgilson    schedule 01.12.2012
comment
@jgritty: Нет, это неправильно. Это добавит вложенный список, который не нужен OP.   -  person jdi    schedule 01.12.2012
comment
@jdi строка 52 на самом деле просто пробел перед следующим определением в строке 53   -  person Jacob J Callahan    schedule 01.12.2012
comment
@jgritty, это отличается от того, что делает сейчас OP. Попробуйте: a = []; a.extend(list((1,))); print(a) дает вам [1], а не [[1]]   -  person mgilson    schedule 01.12.2012
comment
Ненавижу это говорить... но даже с этим журналом интерпретатора это все равно не имеет смысла. В вашем методе genList() нет ничего, что указывало бы на то, что вы возвращаете тип вместо экземпляра списка. Тем не менее ваш вывод показывает, что genList() возвращает тип класса.   -  person jdi    schedule 01.12.2012
comment
Точно @jdi ... я не могу понять, почему он не возвращает фактический список.   -  person Jacob J Callahan    schedule 01.12.2012
comment
Я проверю ваш код, если вы опубликуете рабочую версию.   -  person jdi    schedule 01.12.2012
comment
добавил для вас ссылку на pastebin   -  person Jacob J Callahan    schedule 01.12.2012
comment
Пример кода, кажется, отлично работает для меня, Python 2.7.3 в Windows.   -  person jgritty    schedule 01.12.2012
comment
Отлично работает в питоне 3.3. Вы действительно используете Python 3.0?   -  person jdi    schedule 01.12.2012
comment
коррекция 3.2.2. Завтра попробую что-нибудь другое, спасибо   -  person Jacob J Callahan    schedule 01.12.2012
comment
У меня на 3.2 тоже все работало   -  person jgritty    schedule 01.12.2012


Ответы (2)


В ваших примерах нет ничего, что указывало бы на источник проблемы, но это означает, что вы каким-то образом возвращаете тип объекта, а не экземпляр объекта. Все, что я могу предложить на данный момент, это предложить другой способ переработать метод genList() и посмотреть, решит ли он вашу проблему волшебным образом.

Вы можете попробовать передать один и тот же список результатов через рекурсию вместо того, чтобы возвращать много временных:

def genList(self, numList=None):
    if numList is None:
        numList = []

    if self.leftChild != 'none':
        self.leftChild.genList(numList)

    numList.append(self.Value)

    if self.rightChild != 'none':
        self.rightChild.genList(numList)

    return numList

results = rootNode.genList()

Кроме того, есть ли причина, по которой вы используете 'none' вместо None? Я бы просто использовал None вместо строки.

Предлагаемые мной изменения в вашей версии находятся здесь: http://pastebin.com/FGf8Lcdu

А вот вывод того же кода интерпретатора под python3.3:

In [1]: %cpaste
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
:>>> import BinTreeNode as BTN
:>>> node1 = BTN.BinaryTreeNode(5)
:>>> node2 = BTN.BinaryTreeNode(2)
:>>> node3 = BTN.BinaryTreeNode(12)
:>>> node3 = BTN.BinaryTreeNode(16)
:>>> node4 = BTN.BinaryTreeNode(4)
:>>> node5 = BTN.BinaryTreeNode(13)
:>>> node1.addChild(node2)
:>>> node1.addChild(node3)
:>>> node1.addChild(node4)
:>>> node1.addChild(node5)
:<EOF>

In [2]: node4.genList()
Out[2]: [4]

In [3]: node1.genList()
Out[3]: [2, 4, 5, 13, 16]
person jdi    schedule 01.12.2012
comment
Мои предлагаемые изменения в вашем pastebin: pastebin.com/FGf8Lcdu (хотя у меня это отлично работает в python2.7.3 и питон 3.3) - person jdi; 01.12.2012
comment
Сделаю. Вы можете вставить результаты вашего интерпретатора? вы можете использовать те же вызовы, что и я. - person Jacob J Callahan; 01.12.2012
comment
Спасибо за вашу помощь @jdi - person Jacob J Callahan; 01.12.2012

Я бы добавил пару отпечатков, чтобы увидеть, какой фактический тип, когда он выдает ошибку, например:

def genList(self):
    #recursively generates a sorted list of child node values
    numList = []
    if self.leftChild != 'none':
        print self.leftChild.genList(), type(self.leftChild.genList())
        numList.extend(self.leftChild.genList())  #error
    numList.extend(list((self.Value,)))
    if self.rightChild != 'none':
        print self.rightChild.genList(), type(self.rightChild.genList())
        numList.extend(self.rightChild.genList()) #error
    return numList

Не такое уж дикое предположение... Попробуйте вместо list((self.Value,)) использовать [self.Value]. Я чувствую, что это сработает... :-)

person vkontori    schedule 01.12.2012
comment
я выполнил команды через интерпретатор и получил ответ, что они просто возвращают тип списка по какой-то причине вот результат ‹class 'list'› - person Jacob J Callahan; 01.12.2012
comment
@JacobJCallahan: первым напечатанным элементом был список или это был второй элемент? - person jdi; 01.12.2012
comment
То, что было напечатано @jdi, было результатом запуска genList() на узле без дочерних элементов. поэтому проблема в том, что он возвращает тип вместо самого списка - person Jacob J Callahan; 01.12.2012
comment
также [self.Value] возвращает то же самое - person Jacob J Callahan; 01.12.2012
comment
@JacobJCallahan: Нам нужно увидеть больше контекста, чтобы понять, что здесь не так. В вашем текущем примере нет ничего, что указывало бы на то, где будет ошибка. - person jdi; 01.12.2012
comment
это весь контекст, который имеет значение. другой код состоит из других функций, у которых нет проблем - person Jacob J Callahan; 01.12.2012
comment
Если бы в другом коде не было проблем, вы бы не увидели эту ошибку. Мы установили, что эта строка numList.extend(list((self.Value,))) немного странная, но, похоже, делает то, что нужно. Кроме этого, вы не даете нам многого для продолжения. - person jgritty; 01.12.2012
comment
@jgritty надеюсь, что последнее редактирование поможет. это все, что мне нужно продолжать - person Jacob J Callahan; 01.12.2012
comment
@JacobJCallahan: К сожалению, нет. Ваш единственный выбор - опубликовать весь свой код в pastebin или что-то в этом роде. - person jdi; 01.12.2012