Iterators
An Iterator is an object that has countable sequenced values. The iterator method will not run past the final value if used in a for loop as long as the default built-in functionality of iteration is not overridden by a call to __next__() as explained shortly.
planets = ("Earth", "Venus", "Saturn")
space_travel = iter(planets)
print(next(space_travel))
print(next(space_travel))
print(next(space_travel))
print(next(space_travel))
print(next(space_travel))
print(next(space_travel))
# results in:
Earth
Venus
Saturn
# and the final 3 next calls produce nothing because the end of the
# tuple was reached.
Strings are also iterable one character at a time.
A call to the iter() member function has to be returned into an object variable. If you want to use a for loop in a more traditional way do it directly on the tuple, list, set or dictionary instead of its iterable object so that it will automatically stop at the last member of the tuple, list, set or dictionary object.
The iterator's built-in next goes by one unit and the built-in iter establishes some type of property associated with the object's self-referencing self identifier. The __iter__() and __next__() function calls override those default functions of an iterable object.
The __next__() function must return the next value unless overriden.
The __iter__() function must return the self-referencing identity variable for the object, possibly with a property variable attached to it.
Somehow it looks like you're going to need this StopIteration in a raise call as part of an else: clause on the back end of an if conditional clause to get a for loop to stop. It is just the nature of the beast using a next overriding function that it will keep going forever even if the conditional is met.
class OddNumbers:
def __iter__(oddself):
oddself.a = 7
return oddself
def __next__(oddself):
if oddself.a <= 30:
x = oddself.a
oddself.a += 2
return x
else:
raise StopIteration
# without the else clause the odd numbers would just keep
# printing out even if oddself was greater than 30. It doesn't
# really make sense compared to the normal way of using if
# conditionals, but is just the way it is when using the
# __next__()
Odds = OddNumbers()
iterable_odds = iter(Odds)
for a in iterable_odds:
print(a)
------------------------------ another example ----------------
class OddNumbers:
def __iter__(oddself):
oddself.a = 9
return oddself
def __next__(oddself):
x = oddself.a
x += 2
return x
Odds = OddNumbers()
Johns_Odds = iter(Odds)
print(next(Johns_Odds))
print(next(Johns_Odds))
print(next(Johns_Odds))
print(next(Johns_Odds))
print(next(Johns_Odds))
# prints 11 over and again because x is just a reference for oddself.a.
# If oddself.a itself never gets adjusted then neither will x!!
# in other words, equal sign (=) assignments of an object's self entity is a copy and not by reference.
No comments:
Post a Comment