Reputation:
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
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
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
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
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