Reputation: 2903
Can somebody explain how the __next__
works with the code below? I know 'next' is used for iterators to grab the next item of an iterable, usualy with next()
.
I know the __iter__
part gets executed because of list()
call which executes __next__
. But __next__
keeps executing, almost like a while loop? Until StopIteration is executed?
Also, where are all the 'return' elements getting stored under __next__
? Is it all just stored in memory until return self
under __iter__
returns it to the calling function?
class FRange(object):
def __init__(self, start, stop=None, step=None):
if stop is None:
self.i = 0
self.stop = start
self.step = 1
elif step is None:
self.i = start
self.stop = stop
self.step = 1
else:
self.i = start
self.stop = stop
self.step = step
def __iter__(self):
return self
def __next__(self):
if self.i < self.stop and self.step > 0:
self.i += self.step
return self.i - self.step
elif self.i > self.stop and self.step < 0:
self.i += self.step
return self.i - self.step
else:
raise StopIteration
def rangeFloat(args):
return list(FRange(*args))
The code above produces for example:
For args = [-1.1, 2.4, 0.3], the output is
rangeFloat(args) = [-1.1, -0.8, -0.5, -0.2, 0.1, 0.4, 0.7, 1, 1.3, 1.6, 1.9, 2.2].
Upvotes: 0
Views: 35
Reputation: 280485
list
basically works like
def list(thing):
result = []
for item in thing:
result.append(item)
return result
and a for
loop:
for item in thing:
# loop body
works like
iterator = iter(thing):
while True:
try:
item = next(iterator)
except StopIteration:
break
# loop body
Putting these things together, list
calls your FRange
instance's __iter__
method to get an iterator; in this case, the iterator is your FRange
instance itself. It then calls __next__
repeatedly and appends all __next__
return values to the list until __next__
raises StopIteration
. Once StopIteration
is raised, list
returns the list it built.
Upvotes: 2