Python Generator and Iterator Details
- 2021-12-11 18:34:58
- OfStack
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
yield
0
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