Python Generator and Iterator Details

  • 2021-12-11 18:34:58
  • OfStack

Directory 1, Generator 2. Iterators and iterative generators

1. Generator

Now you can create a list directly through the generator, but due to the limitation of memory, the capacity of the list is definitely limited. If we need a list containing hundreds of elements, but only a few of them are accessed every time we access it, it will waste memory space if the remaining elements are not used.

At this time, the generator ( Generator ) works by generating new data according to some algorithm until one of the specified conditions is met

There are several ways to get the generative expression:

The generator is obtained through the list generator. The sample code is as follows:


g = (x for x in range(10))  #  Generates the list into the column's [] Change into ()
#  Print its type 
print(type(g))  # <class 'generator'>
#  Invoke its elements 
print(g.__next__())  # 0
print(g.__next__())  # 1
print(g.__next__())  # 2
print(g.__next__())  # 3
print(g.__next__())  # 4
#  Use .__next__ Called in the way of 
print(next(g))  # 5
print(next(g))  # 6
print(next(g))  # 7
print(next(g))  # 8
print(next(g))  # 9
#  Use next() Method call of 
print(next(g))  #  An error is reported when the data cannot be called  StopIteration

Call as much as you need, and what you don't call won't be generated, so it won't take up memory space. You can use a loop structure to call as needed


g = (x for x in range(10))  #  Generates the list into the column's [] Change into ()
skip = True  #  Judgement condition 
count = 0  #  Number of calls 
while skip:
    count += 1  #  Cycle 1 Times +1
    print(next(g))
    if count > 9:
        break  #  Out of the loop 

Use the function to use the yield Keyword to complete a generator to generate the first 20 numbers of Fibonacci sequence. The example code is as follows:


def fun(length):
    a, b = 0, 1
    for _ in range(length):
        a, b = b, a + b
        yield a


fib = fun(20)
print(type(fib))  # <class 'generator'>  #  Print type 
count = 0
while count < 20:
    # 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
    print(next(fib), "", end="")
    count += 1

The process is as follows:

During execution, you encounter yield Keyword will be paused, and the next call will continue from the last paused position, because it is a loop statement, and all will jump directly to for Statement

If you call the yield If you need to pass a value to it, you need to use the .send() Method.

The sample code is as follows:


def fun(num):
    n = 0
    for i in range(num + 1):
        n += i
        ret = yield n
        print(f" This is + To {ret} The first part of {i + 1}  Times ")


g = fun(3)
print(g.send(None))
print(g.send('3'))
print(g.send('3'))
print(g.send('3'))
'''
--- Output result ---
0
 This is + To  3  The first part of  1  Times 
1
 This is + To  3  The first part of  2  Times 
3
 This is + To  3  The first part of  3  Times 
6
'''

send The addition of can make the generator more flexible, but it is important to note that the first time the generator is called send() Method, the parameters can only be None Or an exception will be thrown. Of course, you can also call the send() Method is called once before yield0 Method, so that the generator enters the yield Expression.

2. Iterators and iterative generators

Objects that can be iterated are generators, tuples, lists, collections, dictionaries, strings, and so on

Pass collections Adj. Iterable Function combination isinstance (object, classinfo) to determine that one object is not an iterable object

Iteration is one way to access the elements of a collection. Iterator is an object that can remember the position of traversal. The iterator object is accessed from the first element of the collection until all the elements are accessed. Iterators can only go forward, not backward. A generator is also an iterator.

Can be next () An object called by a function and continuously returning the next 1 value is called an iterator: Iterator You can use the isinstance() Determine whether an object is Iterator Object:

Note: Iterable not 1 is definitely a generator, but generator 1 is definitely iterative.

Put tuples, lists, collections, dictionaries, strings, etc. Iterable Become Iterator You can use the iter() Function

Iterable And Iterator**** The difference is that Iterable It can be used as for A general term for loop objects; And Iterator Object needs to be called by the next () function to continuously return the next data until it is thrown when there is no data StopIteration Error, and its length will not be known until then, so the calculation of Iterator is lazy, only n ext() The function calls him to return the result, Iterator It can even represent an infinite data stream, such as all natural numbers.


from collections.abc import Iterable, Iterator
a = [1, 2, 3]
b = {1, 2, 3}
c = (1, 2, 3)
d = "123"
e = 123
f = (x for x in range(5))
#  Print data type 
print(type(a))  # <class 'list'>
print(type(b))  # <class 'set'>
print(type(c))  # <class 'tuple'>
print(type(d))  # <class 'str'>
print(type(e))  # <class 'int'>
print(type(f))  # <class 'generator'>
print("-" * 20)

#  Whether print is an iterable object 
print(isinstance(a, Iterable))  # True
print(isinstance(b, Iterable))  # True
print(isinstance(c, Iterable))  # True
print(isinstance(d, Iterable))  # True
print(isinstance(e, Iterable))  # False
print(isinstance(f, Iterable))  # True
print("-" * 20)
#  All but strings are iterative objects 

#  Whether print is an iterator 
print(isinstance(a, Iterator))  # False
print(isinstance(b, Iterator))  # False
print(isinstance(c, Iterator))  # False
print(isinstance(d, Iterator))  # False
print(isinstance(f, Iterator))  # True
#  Only f( Generator ) Is an iterator 
print("-" * 20)


#  Pass iter() Convert an iterable to an iterator 
print(isinstance(iter(a), Iterator))  # True
print(isinstance(iter(b), Iterator))  # True
print(isinstance(iter(c), Iterator))  # True
print(isinstance(iter(d), Iterator))  # True

Related articles: