#๐Ÿ”’ How to use `__iter__` and `__next__` for a BST

50 messages ยท Page 1 of 1 (latest)

latent flame
#

If your class has __next__, it's an iterator. For iterators usually one just has __iter__ do return self.

#

(return iter(self) is invalid - it'll cause infinite recursion.)

hallow linden
#

return self doesnt work

#

i get this error

#

TypeError: 'Node' object is not iterable

#

do u wanna see my whole code?

latent flame
#

that'd help, yes

#

and your whole error, too

hallow linden
#
class Node:
    def __init__(self, value=None):
        self.value = value
        self.left = None
        self.right = None
        self.parent = None


class BinarySearchTree:

    def __init__(self, name, root=None):
        self.name = name
        self.root = root
        self.left_most = self.get_left_most()

    def add_all(self, *items):
        for item in items:
            if self.root is None:
                self.root = Node(item)
            else:
                current = Node(item)
                while ((item < current.value) and (current.left is not None)) or (
                        (item > current.value) and (current.right is not None)):
                    if item > current.value:
                        current = current.right
                    elif item < current.value:
                        current = current.left
                if item > current.value:
                    current.right = Node(item)
                    current.right.parent = current
                if item < current.value:
                    current.left = Node(item)
                    current.left.parent = current

    def __str__(self):
        bst = "[" + self.name + "] ";
        if self.root.value is not None:
            bst += self.bst_print(self.root)
#
    def bst_print(self, n):
        s = ""
        s += n.value
        if n.left is not None:
            s += " L:("
            s += self.bst_print(n.left)
            s += ")"
        if n.right is not None:
            s += " R:("
            s += self.bst_print(n.right)
            s += ")"
        return s

    def get_left_most(self):
        temp = self.root
        while temp.left is not None:
            temp = temp.left
        return temp

    def __iter__(self):
        return self

    def __next__(self):
        temp = self.left_most
        if self.left_most.right is not None:
            self.left_most = self.left_most.right
            while self.left_most.left is not None:
                self.left_most = self.left_most.left
            return temp.value
        else:
            found = False
            while not found:
                if self.left_most.parent is None:
                    self.left_most = None
                    found = True
                    return temp.value
                else:
                    if self.left_most.parent.left == self.left_most:
                        self.left_most = self.left_most.parent
                        found = True
                        return temp.value
                self.left_most = self.left_most.parent


if __name__ == "__main__":
    t1 = BinarySearchTree(name="Oak", root=Node())
    t1.add_all(1, 0, 10, 2, 7)
    for x in t1.root:
        print(x)```
hallow linden
latent flame
#

t1 is a BinarySearchTree, which is iterable because it defines __iter__, but t1.root is a Node, which isn't.

hallow linden
#

so how do i fix this? i dont think we're supposed to define __iter__ inside Node itself

#

unless thats necessary

summer salmon
#

Perhaps you should not have a next method at all, but rather just an iter method

hallow linden
summer salmon
#

If you have a next method, then the iter method should just return self, not iter(self) (which would be recursive anyways...)

latent flame
hallow linden
#

i realize i think the teacher made a typo

#

because t1.root makes no sense

#

if i do for x in t1:
print(x)

#

then it works slightly better but im still getting error

#

is there a way to make a variable outside of a constructor in a python class that can be updated by other methods?

summer salmon
hallow linden
#

cuz like the error im getting now has to do with getting the leftMost aka the very left of the tree

#

and in my implementation

#
    def __init__(self, name, root=None):
        self.name = name
        self.root = root
        self.left_most = self.get_left_most()```
#

i did this

#

which get_left_most

#

basically finds it given self.root

#

but

#

i dont think thats working as intended

#

bc it says that left most is None TYpe

#

from the start

#

no matter what

#

wait hmm

#

yeah

#

thats so weird

#
class Node:
    def __init__(self, value=None):
        self.value = value
        self.left = None
        self.right = None
        self.parent = None


class BinarySearchTree:

    def __init__(self, name, root=None):
        self.name = name
        self.root = root
        self.left_most = root

    def add_all(self, *items):
        for item in items:
            if self.root.value is None:
                self.root = Node(item)
                self.left_most = self.root
            else:
                current = Node(item)
                while ((item < current.value) and (current.left is not None)) or (
                        (item > current.value) and (current.right is not None)):
                
                    if item > current.value:
                        current = current.right
                    elif item < current.value:
                        current = current.left
                if item > current.value:
                    current.right = Node(item)
                    current.right.parent = current
                if item < current.value:
                    current.left = Node(item)
                    current.left.parent = current
                    if item < self.left_most.value:
                        self.left_most = current

    def __str__(self):
        bst = "[" + self.name + "] ";
        if self.root.value is not None:
            bst += self.bst_print(self.root)

    def bst_print(self, n):
        s = ""
        s += n.value
        if n.left is not None:
            s += " L:("
            s += self.bst_print(n.left)
            s += ")"
        if n.right is not None:
            s += " R:("
            s += self.bst_print(n.right)
            s += ")"
        return s

    def __iter__(self):
        return self```
#
    def __next__(self):
        temp = self.left_most
        print(temp.value)
        if self.left_most.right is not None:
            self.left_most = self.left_most.right
            while self.left_most.left is not None:
                self.left_most = self.left_most.left
            return temp.value
        else:
            found = False
            while not found:
                if self.left_most.parent is None:
                    self.left_most = None
                    found = True
                    return temp.value
                else:
                    if self.left_most.parent.left == self.left_most:
                        self.left_most = self.left_most.parent
                        found = True
                        return temp.value
                self.left_most = self.left_most.parent


if __name__ == "__main__":
    t1 = BinarySearchTree(name="Oak", root=Node())
    t1.add_all(1, 0, 10, 2, 7)
    for x in t1:
        print(x)
#

this is my new code

#

and i get the error

#

the print is just for me to check the values of temp

#

for debugging

#

but how is it none type if its the left_most value

#

which is updated during add_all

hallow linden
#

i fixed it but ty yall

fallow nestBOT
#
Python help channel closed

This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.

#

๐Ÿ”’ How to use __iter__ and __next__ for a BST