user13507706
user13507706

Reputation:

How do iterators know what item comes next?

As far as I understood it, iterators use lazy evaluation, meaning that they don't actually save each item in memory, but just contain the instructions on how to generate the next item.

However, let's say I have some list [1,2,3,4,5] and convert it into an iterator doing a = iter([1,2,3,4,5]).

Now, if iterators are supposed to save memory space because as said they contain the instructions on how to generate the next item that is requested, how do they do it in this example? How is the iterator a we created supposed to know what item comes next, without saving the entire list to memory?

Upvotes: 1

Views: 146

Answers (4)

ShadowRanger
ShadowRanger

Reputation: 155704

In this case, the iterator does in fact store a reference to the underlying list (along with the present index) internally, so it is keeping the list alive. For iterators that don't use memory, look at generators or iterators backed by lazy types like range, both of which can store just enough information to produce the next value and the information on the end condition, without storing all the values up front.

A generator like:

def makes_numbers(n):
    i = 1
    while i <= n:
        yield i
        i += 1

essentially freezes the state of the frame variables (i, n, and the current instruction) on each yield, producing 1 through 5 without actually storing all of them at once. range itself is basically a lazy sequence that, when an iterator is constructed from it, performs the same work internally (but in a more optimized fashion).

Upvotes: 2

Anuj Sharma
Anuj Sharma

Reputation: 537

Although, ShadowRanger explained answer well. Let me allow it to explain using an example. Every iterator must have these two methods.

 __init__()
 __next__()

next method must return the next value.

class My_iterator:
  def __iter__(self):
    self.x = 1
    return self

  def __next__(self):
    y = self.x
    self.x += 1
    return y

Above, you can see that this method is computing next iterator or more precisely generating next iterator (ShadowRanger explained this above.) If you are using a list then it keeps a reference to it.

Upvotes: 0

Neorem
Neorem

Reputation: 71

Just think for a moment about this scenario ... You have a file of over a million elements, loading the memory of the whole list of elements would be really expensive. By using an iterator, you can avoid making the program heavy by opening the file once and extracting only one element for the computation. You would save a lot of memory.

Upvotes: 0

orlp
orlp

Reputation: 117981

How is the iterator a we created supposed to know what item comes next, without saving the entire list to memory?

It doesn't save the list. It just stores a reference to the list you passed in.

>>> l = [1, 2, 3, 4, 5]
>>> a = iter(l)
>>> next(a)
1

>>> l[1] = 1337
>>> next(a)
1337

Upvotes: 4

Related Questions