I want to write a function called print_iterator_explicit() which prints all of the items in a linked list by making use of the Iterator. However, you are not permitted to use the standard "for ... in" loop syntax - instead you must create the Iterator object explicitly, and print each item by calling the next() method
Use the iter() and next() methods in your function definition - and remember to handle the StopIteration exception!
Below is what I've tried, but the print_iterator_explicit seems to have some problem which I can only print the first element but not the whole list.
class LinkedListIterator:
def __init__(self, head):
self.current = head
def __next__(self):
if self.current == None:
raise StopIteration
else:
item = self.current.get_data()
self.current = self.current.get_next()
return item
class LinkedList:
def __init__(self):
self.head = None
def __iter__(self):
return LinkedListIterator(self.head)
def add(self, item):
new_node = Node(item)
new_node.set_next(self.head)
self.head = new_node
def print_iterator_explicit(items):
it = items.__iter__()
print(it.__next__())
Just as mentioned by @abarnert , you always need a __iter__ method for the iterator class.
class LinkedListIterator:
def __init__(self, head):
self.current = head
def __iter__(self):
return self
def __next__(self):
if not self.current:
raise StopIteration
else:
item = self.current.get_data()
self.current = self.current.get_next()
return item
class LinkedList:
def __init__(self):
self.head = None
def __iter__(self):
return LinkedListIterator(self.head)
def add(self, item):
new_node = Node(item)
new_node.set_next(self.head)
self.head = new_node
Now that your class is iterable, you can use "for...in" loop:
test_list = LinkedList()
test_list.add(1)
test_list.add(2)
test_list.add(3)
for item in test_list:
print(item)
Please check the tutorial here.
You can use the yield keyword to make a generator so you dont have to implement __next__()
class LinkedList:
def __init__(self):
self.head = None
def __iter__(self):
curNode = self.head
while curNode:
yield curNode.value
curNode = curNode.nextNode
def add(self, item):
new_node = Node(item)
new_node.set_next(self.head)
self.head = new_node
And in your print_iterator_explicit function you can do it like this
def print_iterator_explicit(items):
iterator = iter(ll)
while True:
try:
print(next(iterator))
except StopIteration:
break
Check out this link for more information on iterators and generators: Iterators and generators
A little side note: your head variable is behaving like a tail. In a linked list the first node is called the head and the last is called the tail
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With