2016-10-29 4 views
0

Я пытался выяснить способ получения значения int от генератора, но механизм сценариев бросает мне ошибки.Возвращает int из генераторов - Python

def inorderTraversal(self, node): 
     if(node.left): 
      for n in self.inorderTraversal(node.left): 
       yield n[0] 
     yield node.data[0] 
     if(node.right): 
      for n in self.inorderTraversal(node.right): 
       yield n[0] 

Ошибка:

File "ac.py", line 142, in inorderTraversal
yield n[0] TypeError: 'int' object is not subscriptable

где

n = {10,"X"}. Я пытался найти его, но ни одно решение, которое я знаю, не отвечает моим потребностям.

+0

Вы хотите вернуть узлы или их значения? Похоже, что 'yield node.data [0]' возвращает значение, а две for-loops обращаются к возвращаемому значению, как если бы это был узел вместо значения. – Mephy

+1

Вы на 100% уверены, что это то, что означает 'n'? Или вы догадываетесь? Положите печатную линию, чтобы быть уверенным. – Carcigenicate

+1

Уверены ли вы в свой тип 'n', он говорит, что это просто' int' (вероятно, из рекурсивного выхода), и вы описали 'set', который не является индексируемым. Вы смешиваете рекурсию с генераторами, если вы действительно хотите это сделать, а затем посмотрите на «yield from ...», вы можете заменить 'for n in self.inorderTraversal (node.left): выход n' с 'yield from self.inorderTraversal (node.left)' – AChampion

ответ

0

если ваш yield node.data[0] верен, то когда вы делаете yield n[0] в рекурсивном случае, вы делаете yield node.data[0][0] в этой ветке. Поэтому замените его на yield n, потому что рекурсивный случай уже дает вам то, что вам нужно, вам нужно только передать его.

Кроме того, при проектировании дерева вы обычно делаете это так, чтобы хранилище .data, а также данные, которые пользователь вашего дерева хочет сохранить в нем и не беспокоиться о том, что это такое или как он выглядит, поэтому вы обычно делаете yield node.data.

Также как вы находитесь в python 3, вы можете использовать yield from, который является ярлыком для такого типа for-loop.

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

def inorderTraversal(self, node): 
    if node.left: 
     yield from self.inorderTraversal(node.left) 
    yield node.data 
    if node.right: 
     yield from self.inorderTraversal(node.right) 

как вы не снабженным Minimal, Complete, and Verifiable example вашей проблемы, я могу только догадываться, так

Позволяет увидеть пример дерева Код:

class Node: 
    def __init__(self, data, left=None, right=None): 
     self.data = data 
     self.left = left 
     self.right = right 

с этим позволяет построить образец дерева, например, o пе в wikipedia

sample tree

test1 = Node(6, 
      Node(2, 
        Node(1), 
        Node(4, 
         Node(3), 
         Node(5) 
         ) 
       ), 
      Node(7, 
        None, 
        Node(9, 
         Node(8) 
         ) 
       ) 
      ) 

позволяет сделать это снова с вашей структурой данных [междунар, ул]

test2 = Node([6,"F"], 
      Node([2,"B"], 
       Node([1,"A"]), 
       Node([4,"D"], 
         Node([3,"C"]), 
         Node([5,"E"]) 
        ) 
       ), 
      Node([7,"G"], 
       None, 
       Node([9,"I"], 
         Node([8,"H"]) 
        ) 
       ) 
      ) 

теперь самое интересное, функция Симметричного, первая ваша

def inorderBad(node): 
    if node.left: 
     for n in inorderBad(node.left): 
      yield n[0] 
    yield node.data[0] 
    if node.right: 
     for n in inorderBad(node.right): 
      yield n[0] 

позволяет проверить его на test2

>>> list(inorderBad(test2)) 
Traceback (most recent call last): 
    File "<pyshell#0>", line 1, in <module> 
    list(inorderBad(test2)) 
    File "C:\Users\David\Documents\Python Scripts\stackoverflow_test.py", line 26, in inorderBad 
    for n in inorderBad(node.left): 
    File "C:\Users\David\Documents\Python Scripts\stackoverflow_test.py", line 27, in inorderBad 
    yield n[0] 
TypeError: 'int' object is not subscriptable 
>>> 

выглядит знакомым? ошибка, как я сказал, является рекурсивным случаем n[0], когда вы достигаете нижнего узла (в этом случае), оно дает данные [0] (в этом случае 1), в Узле выше (B) оно получает это значение и пытается выход снова только на этот раз попробовать, чтобы получить первое значение этого и не в этом отношении, как ошибки сказал

Теперь давайте это исправить

def inorder2(node): 
    if node.left: 
     for n in inorder2(node.left): 
      yield n 
    yield node.data[0] 
    if node.right: 
     for n in inorder2(node.right): 
      yield n   

и проверить его

>>> list(inorder2(test2)) 
[1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> 

работу как ожидается, попробуем с другим

>>> list(inorder2(test1)) 
Traceback (most recent call last): 
    File "<pyshell#6>", line 1, in <module> 
    list(inorder2(test1)) 
    File "C:\Users\David\Documents\Python Scripts\stackoverflow_test.py", line 35, in inorder2 
    for n in inorder2(node.left): 
    File "C:\Users\David\Documents\Python Scripts\stackoverflow_test.py", line 35, in inorder2 
    for n in inorder2(node.left): 
    File "C:\Users\David\Documents\Python Scripts\stackoverflow_test.py", line 37, in inorder2 
    yield node.data[0] 
TypeError: 'int' object is not subscriptable 
>>> 

Естественно, это не так, потому что inorder2 недостаточно общий, также в вашей текущей реализации, что, если вы хотите использовать строку вместо этого? есть вы думаете, на что ?, в общем те, касаются не должны иметь отношение к этой конкретной функции, она должна только предоставить все данные Симметричного

так общее заказовМои и добавив yield from является

def inorder(node): 
    if node.left: 
     yield from inorder(node.left) 
    yield node.data 
    if node.right: 
     yield from inorder(node.right) 

test

>>> list(inorder(test2)) 
[[1, 'A'], [2, 'B'], [3, 'C'], [4, 'D'], [5, 'E'], [6, 'F'], [7, 'G'], [8, 'H'], [9, 'I']] 
>>> list(inorder(test1)) 
[1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> 
+0

Мне нужны только целые ключи от узлов. Данные, хранящиеся на каждом узле, в настоящее время находятся в форме [** int **, "string"]. Я сомневаюсь, что 'yield n [0]' станет рекурсивным, так как я также печатаю 'n [0]' непосредственно перед оператором yield, а вывод печати - именно то, что мне нужно. Я также поменял 'yield from' вместо 'yield', но ничего не изменилось. – Akt

+0

@Akt Я сделал обновление, сравним их с вашим кодом. Я пытаюсь найти разницу, если вы все еще застряли, а затем обновите свой вопрос с помощью изменения, которое вы пытаетесь, которое все еще не работает, или поместите фактический рабочий код и пример, чтобы мы могли его протестировать ... – Copperfield

+0

Да, я эмулировал это решение, и теперь функция работает без ошибок. Теперь я получаю это, из-за рекурсии 'yield n.data [0]' пытался индексировать int в данных [0]. Спасибо за ваше время – Akt

2

Необходимо заменить yield n[0] на yield n. Вы уже уступаете (целочисленному) значению узла, поэтому нет необходимости индексировать его дальше.

Редактировать: Пояснение добавлено.

+0

Хотя я понимаю, что у вас нет репутации для комментариев, это не ответ. – Carcigenicate

+0

@Carcigenicate it * is * ответ, а не самый полезный вид :-). –

+0

@ JimFasarakis-Hilliard Он говорит OP, чтобы попробовать что-то, не сообщая им определенно, в чем проблема. Думаю, на каком-то огромном участке его можно было считать одним, но только очень тонким. – Carcigenicate

0
n = {10,"X"} 

print(n[0]) 

Урожайность

TypeError: 'set' object does not support indexing 

Не точная ошибка, но я проверяю это на Android IDE, так что не совсем меня удивляет.

Тогда ответ заключается в том, что вы пытаетесь подстроить набор, но что это значит? Наборы неупорядочены, поэтому нет «0-го» элемента набора. Если вам нужен произвольный доступ, вам нужно переключиться на список.

Или, если вы ищете простой временный контейнер, кортежи индексируются.

Если n - это данные узла, вы можете просто создать класс Node, а затем получить доступ к полю напрямую, а не индексировать.

+0

Я также попытался использовать n = [10, 'X'], а затем напечатал ** n [0] **, оператор печати работает так, как ожидалось. Его единственный выход 'n [0]', который терпит неудачу. – Akt

Смежные вопросы