The difference between generators and iterators and iterable objects in python

Let’s briefly summarize the relationship between the three:

    Both generators and iterators are iterable objects, and generators are a special kind of iterator. For both generators and iterators, we can use the next() function to get the next return value, and of course we can use for. ..in... to get their return value, because the essence of for...in... is to continuously call the next() method on the object, the essence of for...in... See for... in ... Internal Implementation Principles .

Then explain separately:

    Iterable object: Generally speaking, in python, an object that can iteratively read a piece of data for us to use through a for...in... statement is called an iterable object (Iterable) such as a list (list) , tuple (tuple), etc., we can also use isinstance(obj, Iterable) to determine whether an object is an iterable object. If the object is an iterable object, the result of isinstance returns True

>>> from collections import Iterable
>>> obj = ['a','b',1,2]
>>> isinstance(obj, Iterable)
True
>>> obj_1 = {3,5,6,7,2}
>>> isinstance(obj_1, Iterable)
True

    Iterator: An iterator is an object that can record the address of the data of each iteration of the iterable object, so that each iteration can return the next piece of data. In python, only one class implements the __iter__ method and __next_ _ method, then the instance object of this class is an iterator. We can use isinstance(obj_1, Iterator) to determine whether an object is an iterable object, and if so, isinstance returns True.

from collections import Iterator

class Desc(object):
    def __iter__(self):
        pass
    
    def __next__(self):
        pass

def main():
    print(isinstance(Desc(), Iterator))

if __name__ == '__main__':
    main()

The result of executing the above code is True

    Generators and iterators are implemented differently. Generators can be implemented through generator comprehension or the yield keyword. The two ways are as follows :

>>> gen = (i for i in range(10000))
>>> gen
<generator object <genexpr> at 0x00000000035DE200>
def fib(n):
    current = 0
    num1, num2 = 0, 1
    while current < n:
        num = num1
        num1, num2 = num2, num1 + num2
        current += 1
        yield num
    return 'done'
In [31]: F = fib(5)

In [32]: next(F)
Out[32]: 1

In [33]: next(F)
Out[33]: 1

In [34]: next(F)
Out[34]: 2

In [35]: next(F)
Out[35]: 3

In [36]: next(F)
Out[36]: 5

In [37]: next(F)
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-37-8c2b02b4361a> in <module>()
----> 1 next(F)

StopIteration: done

For the generator created using the yield method above, when we call next(), the function fib will return the value after yield and suspend the function fib. When we use next() to call again, the function The next logic of fib (that is, while) will continue to be executed. When the while loop is over, if you use next() to call the function fib, a StopIteration exception will be thrown instead of returning done. If you want to get the return value, you must Catch the exception.

Conclusion: This article may not be very clear in language. If you have any doubts or corrections, please discuss in the comment area.





Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325725859&siteId=291194637