15. Iterators: Tools
1. Iterable objects:
Officially, as long as the _iter_ method is an iteratable object
list,dict,str,set,tuple -- Iterative objects, flexible to use
# Method 1: list.__iter__() dict.__iter__() # Method 2: View source code # Method 3: print(dir(list)) # Officially, as long as the _iter_ method is an iteratable object
2. Iterator:
Official Statement: As long as you have _iter_ method _next_ method, it is an iterator
f = open("",'w') f.__iter__() f.__next__()
Converting Iterable Objects into Iterators
lst = [1,2,3,4,6] new_lst = lst.__iter__()#Converting Iterable Objects into Iterators new_lst.__iter__() new_lst.__next__() print(new_lst.__next__())#Get one value at a time, get the first value for the first time, and push back later #Write for i in lst(): print(i) lst = [1,2,3,4,6] count = len(lst) new_lst = lst.__iter__() while count: print(new_lst.__next__()) count -= 1 #The essence of for lst = [1,2,3,4,6] new_lst = lst.__iter__() while 1: try: print(new_lst.__next__()) except: break
3. Summary:
Iterable objects:
Advantages: Flexible to use, you can view values directly
Disadvantage: It occupies memory and cannot iterate over values
Iterator:
Advantages: memory savings, lazy mechanisms
Disadvantage: Flexible use, cumbersome operation, unable to view elements directly
The characteristics of iterators:
- One-time (no more after use)
- Can't retreat
- Lazy mechanism (saving memory)
Iterable object: with _iter_() method
Iterator: with _iter_() method and _next_() method
Time to use an iterator: Use an iterator when there is a large amount of data in the container
16. Generator:
Iterator: A built-in space-saving tool in python
The essence of a generator is an iterator.
The difference between generators and iterators:
Iterator: python comes with it
Generator: written by programmers
Write a generator:
Rewriting return from a function to yield is a generator, and return and yield are both returns:
- Both return and yield are returned
- Both return and yield can be written multiple times
- return executes only once and yield executes multiple times
- A next corresponds to a yield, which records where it stays. Exceeding will result in errors.
g = func()# generates a generator
Generators can use for loops to take values
yield from -- returns elements of an iterative object one by one
Within a function, yield can pause for and while loops
def func(): print(123) yield "Hello" print(321) yield "Hello" print(func()) #RESULTS: <generator object func at 0x000001913911F0A0> g = func() g.__inter__() print(g.__next__()) #Will record the location of stay def func(): if 3 > 2: yield "Hello" if 4 > 2: yield "Hello" yield "Hello everyone" g = func() print(g.__next__()) print(g.__next__()) print(g.__next__()) ''' //Result: //Hello //Hello //Hello everyone ''' #for loop for i in g: print(i)
Pit: New generators will be generated
#Every time it's a new generator print(foo().__next__()) print(foo().__next__()) #Only one generator is generated by assignment g = foo()
def foo(): for i in range(10): pass yield i count = 1 while 1: yield count count += 1 g = foo() #Print (next(g) = print (g. next ()) - Recommended use of next(g) print(next(g)) print(next(g)) print(next(g)) #next can stop in while ''' //Result: 9 1 2 '''
seed() -- Understanding
#send() can only pass None for activation for the first time, otherwise it will report an error, and it can transmit various data in the future. def func(): a = yield "send activation" print(a) b = yield "send start" g = func() print(g.send(None)) print(g.send(123))
The generator should have scenarios:
#When there is a lot of data def func(): lst = [] for i in range(1000000): lst.append(i) return lst print(func()) #Generator Improvement def func(): for i in range(1000000): yield i g = func() for i in range(50): print(next(g))
yield from -- Returns iteratable objects one by one
def func(): list1 = ["Breeding of cattle and sheep","Grandma's Peanut Rice","Guardian Dragons","share chatting day","Uncle Pop","Old Godmother"] yield from list1 #Yield list 1 returns the entire list directly g = func() print(next(g)) print(next(g)) ''' //Result: //Breeding of cattle and sheep //Grandma's Peanut Rice ''' def func(): list1 = ["Breeding of cattle and sheep","Grandma's Peanut Rice","Guardian Dragons","share chatting day","Uncle Pop","Old Godmother"] lsit2 = ["Raccoon","Daddy","Kissing","Spicy Hot Pot","Braised chicken","Well cap"] yield from list1 yield from list2 g = func() #Only when lsit1 is returned will list2 be returned print(next(g)) print(next(g)) print(next(g))