0

I have a class of the node which contain his parent and want to create iterator on it. Here is my try:

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

    def __iter__(self):
        self = self.parent

    def __next__(self):
        if self.parent is None:
            raise StopIteration
        else:
            self = self.parent
            return self

But when I try to loop over the instance, it's never stops and returns the same value, what I did wrong?

4
  • There's nothing in the class to iterate over. What data type is self.parent? Commented Sep 6, 2018 at 19:16
  • You iterate over a collection of Node objects, not a Node itself. Commented Sep 6, 2018 at 19:19
  • Why is your Node class an iterator, you probably want to defined a NodeIterator class, and make Node and iterable, although, normally, Node objects themselves wouldn't be iterable, but some container class, like NodeList or whatever, would be iterable. Commented Sep 6, 2018 at 19:19
  • Also, your __iter__ method returns None, when it should return self since you are implementing an iterator, although, you shouldn't be doing that to begin with. You should be implementing an iterable, where __iter__ returns an iterator. Note, self = self.parent doesn't have an affect on anything, it simply reassigns the self local variable, and then the funciton returns None Commented Sep 6, 2018 at 19:20

1 Answer 1

5

The reason your code doesn't work is that you're trying to keep track of the current node in the iterator by assigning to self, which is just a local variable, so nothing is actually updated.

The correct way would be to extract an iterator class and keep track of the current node there:

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

    def __iter__(self):
        return NodeIterator(self)


class NodeIterator:
    def __init__(self, node):
        self.next_node = node

    def __iter__(self):
        return self

    def __next__(self):
        if self.next_node is None:
            raise StopIteration
        else:
            current_node = self.next_node
            self.next_node = self.next_node.parent
            return current_node

This can be used like so:

root = Node()

inner_1 = Node(root)
leaf_1 = Node(inner_1)

inner_2 = Node(root)
inner_2_1 = Node(inner_2)
leaf_2 = Node(inner_2_1)

for node in leaf_2:
    # will loop through:
    # leaf_2,
    # inner_2_1;
    # inner_2,
    # root
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.