In Python, there are these two concepts confusing. The first iteration is the object (Iterable), the second is an iterator (Iterator), a third generator (Generator), where aside generator.
Iterables
Lists, tuples, strings, etc. are iterables dictionaries, may be used for loop through all the elements can be called iterables (Iterable). Iterable class defines a data structure built in the Python, the collections.abc module, we can use this to detect whether iterables
>>> from collections import Iterable
>>> a = [1,2,3]
>>> isinstance(a, Iterable)
>>> True
>>> b = 'abcd'
>>> isinstance(b, Iterable)
>>> True
These data structures are called the Iterable able, because of its internal implementation of the __iter __ () method, so as to be iterative. When we use a for loop, the interpreter calls the built-in iter () function, before the call first checks whether the object implements __iter __ () method, if you call it Gets an iterator (next speak). Adding no __iter __ () method, but realized __getitem __ () method, the interpreter will create an iterator and get the elements in order. If these methods are not found, it will throw a TypeError exception. Here we custom objects, respectively, to achieve the two methods ( getItem (), iter ())
class MyObj:
def __init__(self, iterable):
self._iterable = list(iterable)
def __getitem__(self, item):
return self._iterable[item]
obj = MyObj([1,2,3])
for i in obj:
print(i)
As described above, there is no method to achieve __iter__, only achieved __getitem__ method, so called Myobj iterables.
Now we realize __iter__ method used here yield syntax to output values (here requires knowledge generator)
class MyObj:
def __init__(self, iterable):
self._iterable = list(iterable)
def __iter__(self):
index = 0
while True:
try:
yield self._iterable[index]
except IndexError:
break
index += 1
obj = MyObj([1,2,3])
for i in obj:
print(i)
Here again let objects called iterables.
Iterator
Iterator can remember the object is a traverse position.
Iterator object began a visit from the first element of the collection until all the elements are accessed session is over. Iterator can only move forward not backward.
As shown above, the iterator (the Iterator) may be inherited iteration (the Iterable), and a method iterator __iter__ __next__ methods must be implemented. Wherein __next__ output method for the next element.
Seen from FIG inherited, iterators must be iterator object is not necessarily iterables iterator
iterator has two basic methods: iter () and next ().
We use iter (iterable) to convert iterables iterator to
the next value using the next (iterator) to obtain the iterator
>>> a = [3,4,5]
>>> a
>>> [3, 4, 5]
>>> iter(a)
>>> <list_iterator object at 0x10b130ba8>
>>> iterator = iter(a)
>>> next(iterator)
>>> 3
>>> next(iterator)
>>> 4
>>> next(iterator)
>>> 5
>>> next(iterator)
Traceback (most recent call last):
File "<input>", line 1, in <module>
StopIteration
As described above, since the object implements the method __next__, we may be obtained by next (iterator) next value iterators until no value, and raise StopIteration end.
Behind the iterator
Iterator iterator is an abstract base class, which is defined in the _collections_abc.py Iterator源码
follows
class Iterator(Iterable):
__slots__ = ()
@abstractmethod
def __next__(self):
'Return the next item from the iterator. When exhausted, raise StopIteration'
raise StopIteration
def __iter__(self):
return self
@classmethod
def __subclasshook__(cls, C):
if cls is Iterator:
return _check_methods(C, '__iter__', '__next__')
return NotImplemented
You can see that it implements __subclasshook__ method, that is, without an explicit inheritance Iterator, only need to implement __iter__ and __next__ method can be called Iterator of virtual sub-class . Here highlights Python duck type, to achieve a specific "agreement" can have a certain behavior.
In addition, it also defines __iter__ own way when we use iter (Iterator) directly back to their own, without any treatment.
iter () function of the two Usage
The official explanation is given in the document:
iter(iterable) -> iterator
iter(callable, sentinel) -> iterator
Get an iterator from an object. In the first form, the argument must
supply its own iterator, or be a sequence.
In the second form, the callable is called until it returns the sentinel.
The first usage: iter (iterable) -> iterator ( converting iterables iterator)
Second Usage: iter (callable, sentinel) - > iterator ( first argument: Any callable object may be a function the second is the flag value, when an object can be called to return the value the iterator raise StopIteration without tag output value )
>>> from random import choice
>>> values = [1,2,3,4,5,6,7]
>>> def test_iter():
>>> return choice(values)
>>> it = iter(test_iter, 2)
>>> it
>>> <callable_iterator object at 0x10b130b00>
>>> for i in it:
>>> print(i)
>>> 7
>>> 1
>>> 7
>>> 3
>>> 1
Flow above code: test_iter function randomly selected from the values in the list a value and returns the call iter (callable, sentinel) function, the sentinel flag value is set to 2, returns a callable_iterator instance, traversing this particular iterator, if the function returns 2 tag value, directly thrown exit the program. This is another little-known usage iter function.
Reproduced in: https: //www.cnblogs.com/PyKK2019/p/11067206.html