reflection:
1, Iterator / iteratable object
1. Iteratable object (memory cost)
The old version of python: range consumes more memory (all the data needed are stored in the list, which is very memory consuming when the amount of data is large)
range implementation process:
from typing import Iterable def range_test(stop): start = 0 result = [] while start < stop: result.append(start) start += 1 return result if __name__ == '__main__': print(isinstance(range_test(10),Iterable)) # Judge whether the returned result is iterative, True print(range_test(10)) # output: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2. Iteratable object (memory saving)
from typing import Iterable # Next contain__next__()Method, each variable+1,Only one number of memory is used at a time class Next(object): """Next class""" def __init__(self, stop, start=-1): self.start = start self.stop = stop def __next__(self): if self.start >= self.stop - 1: raise StopIteration self.start += 1 return self.start
# contain__iter__()method, return call Next class MyRange: def __init__(self, stop): self.stop = stop def __iter__(self): return Next(self.stop)
Using the mode mode and single step execution, you can see that the program executes Next, and each execution generates a data. No memory consumption
for is an iteration (automatically executing _ ITER _, _ next), while is a loop (specify the function manually)
if __name__ == '__main__': print(Next(10).__next__()) # 0 for item in MyRange(10): # for Loop automatic execution__iter__,__next__method print(item) # while loop num = MyRange(10).__iter__() i = 0 while i < 10: print(num.__next__()) # 0,1,2,3,4,5,6,7,8,9 i += 1
3. Iterative object definition
Objects that can be iterated by for are iteratable objects
Object has__ iter__ Methods are all iteratable objects (if there is no _iter _method, it cannot be iterated by for)__ iter__ It is required that the return value must be an iterator (strictly speaking, the return value must have a _next _method)
Common iteratable objects; list,tuple,string,dict
Determine whether each object is an iteratable object:
-
You can use dir() to check whether there is any in all attributes__ iter__ method
-
You can also use hasattr (list, '_iter_') to check whether the list has__ iter__ method. If True is returned, the method is available
Judge whether MyRange(10) is an iterative object:
If print (isinstance (MyRange(10), iteratable) returns True, then MyRange(10) is an iteratable object because there are__ iter__ method
Judge whether Next(10) is an iterative object:
If print (isinstance (Next(10), iteratable) returns False, then Next(10) is not an iteratable object because there is no__ iter__ method
4. Iterator definition
Iterators must have__ iter__ __ next__ Attributes
Core: Pass__ next__ Method to remember the location of the iteration and whether the iteration has been completed
Iterators are special iteratable objects,
It can be iterated by for. When the iterator is iterated by for, it will be executed automatically__ next__ method
Iterators save more memory and give only one number at a time.
Without an iterator, you can't use for, you can only use while
Determine whether Next(10) is an iterator
print(isinstance(Next(10),Iterator) # fast__ next__ Method, but missing__ iter__ method
Note:__ iter__ An iterator must be returned (strictly speaking, the return value must have a _next _method)
2, Generator
Because it is troublesome to implement iterators manually
So python provides a generator object, and the purpose of the generator object is to obtain the iterator object (very efficient)
def fun(): print("stay yield1 front") yield 1 print("stay yield1 Back, yield2 front") yield 2 if __name__ == '__main__': # Verify whether it is a generator print(fun()) # <generator object fun at 0x104d00150> The result is a generator object, but no function is running print(hasattr(fun(),"__iter__")) # True print(hasattr(fun(),"__next__")) # True # To run the generator, you must call__next__ print(fun().__next__()) # 1 / stay yield1 front # Run all results,for Automatic call__next__ for i in fun(): print(i)
be careful:
-
When the python interpreter sees that there is a yield in the function, it will not call the function immediately, but create a generator object first. The generator object remembers the state of the function
-
In the for loop, when it runs to the first yield, it exits temporarily (similar to return, but the difference is that return jumps out permanently and won't go back). When you run again (_next_ remember the location), you will start running after yield 1
-
When next is executed, the yield of the generator object is executed
Generators are special iterators, which are special iteratable objects
Generators are iteratable objects
If you create a generator object (via yield)
yield: Keyword
Remember the state of function execution
When next(g) is executed, yield in G is executed
The difference between yield and return:
return: jump out of the function and don't come back
yield: jump out temporarily and come back
Usage scenario of generator:
Why does the generator save memory: because there are__ next__
The generator is designed to quickly obtain__ iter__ __ next__ Method of
Scenario 1: I need 99999999999999 numbers, and put 1-99999999999999 numbers in the list at once
Scenario 2: I need 999999999999 numbers. I need 1 to generate 1, I need 2 to generate 2 ~ ~ ~ ~ ~ I need 9999999999999 to generate 99999999999
Scenario 2 is the idea of next (generator and iterator)
Reproduced for reference only: http://testingpai.com/article/1605148018144