# Iterators and generators for getting started with python

Posted by kendhal on Mon, 08 Nov 2021 14:10:12 +0100

ps this is the notes I took from the course of egon teacher online, that is, some materials. I hope it can help us make progress together

A concept of iteration

```Iterator is the tool of iteration. What is iteration?
Iteration is a repeated process. Each iteration is an iteration, and the result of each iteration is the initial value of the next iteration```

Give you a simple case

```l=[1,2,3]
count=0
while count < len(l): #iteration
print(l[count])
count+=1```

This is the iteration. The above code is repeated three times and iterated three times. A simple analysis for everyone

```l=[1,2,3]
count=0
while count < len(l): #iteration
print(l[count])
count+=1
#During the first iteration, count=0 = = "output l = =" 1
#At the end of the first iteration, count=count+1=1
#During the second iteration, count = initial value of count after the first iteration = = "output l = =" 2
#At the end of the second iteration, count=count+1=2
#During the third iteration, count = initial value of count after the second iteration = = "output l = =" 3
#At the end of the second iteration, count=count+1=3
#At this time, count=3 is not less than len(l)=3, so the iteration ends
```

Second, why is there an iterator? What is an iteratable object? What is an iterator object?

two point one   Why iterators?

`For sequence types: string, list and tuple, we can use the index method to iteratively extract the contained elements. However, there is no index for dictionary, collection, file and other types. If you want to take out the elements contained in them, you must find an iterative method that does not depend on the index, which is iterator`

two point two   What is an iteratable object?

`Iteratable objects are built-in objects__ iter__ Method, namely obj__ iter__， as follows`
```'hello'.__iter__       # ==The string is an iteratable object
(1,2,3).__iter__       # ==Tuples are iteratable objects
[1,2,3].__iter__       # ==The list is an iterative object
{'a':1}.__iter__       # ==Dictionary is an iterative object
{'a','b'}.__iter__     # ==The collection is an iteratable object
open('a.txt').__iter__ # ==The document is an iterative object```

two point three   What is an iterator object?

```Obj. Can be executed by iterative objects__ iter__ The result of () is the iterator object
The iterator object refers to the built-in__ iter__ Built in__ next__ Object of method```
```#The file type is an iterator object
open('a.txt').__iter__()
open('a.txt').__next__()```
```be careful:
An iterator object must be an iteratable object, and an iteratable object does not have to be an iterator object```

2.4 use of iterator objects

```dic={'a':1,'b':2}
iter_dic=dic.__iter__() #Get the iterator object, and the iterator object has__ iter__ Again__ next__
#But: iterators__ iter__ () the result is still the iterator itself, as shown in the following case:
print(iter_dic.__iter__() is iter_dic) #====>True

print(iter_dic.__next__()) #Equivalent to next(iter_dic)
print(iter_dic.__next__()) #Equivalent to next(iter_dic)
print(iter_dic.__next__()) #Equivalent to next(iter_dic)
# print(iter_dic.__next__()) #Throw an exception StopIteration, or end flag,
#When the value of an iterator is taken clean, its value cannot be taken again
# If an iterator is generated for it, the value ITER can continue_ iter = iter.__ iter__ ()

#With iterators, we can iterate values without relying on the index
iter_dic=dic.__iter__()
while 1:
try:
k=next(iter_dic)
print(dic[k])
except StopIteration:
break
#However, this way of writing is not good. We need to catch exceptions and control next, so we have for

#Based on the for loop, we can no longer rely on the index to get the value
dic={'a':1,'b':2}
for k in dic:
print(dic[k])

#How the for loop works
#1: The DIC of the object after executing in__ iter__ () method to get an iterator object
#2: Execute next (iterator object), assign the obtained value to k, and then execute the loop body code
#3: Repeat process 2 until the exception StopIteration is caught and the loop ends```
```Advantages and disadvantages of iterators:
1. Advantages: unified scheme, more memory saving (there is only one value in memory at the same time)
2. Compared with the index, the desired value cannot be obtained directly. After obtaining, an iterator value must be generated, otherwise an error will be reported```

3, What is a generator:

```Generators (custom iterators) are equivalent to iterators
yield is similar to return, but the function will not end after returning the result, and it will still be executed```

That is, as long as the function contains the yield keyword, the result of the function name () is the generator, and the function internal code will not be executed

```def func():
print('====>first')
yield 1
print('====>second')
yield 2
print('====>third')
yield 3
print('====>end')

g=func()
print(g) #<generator object func at 0x0000000002184360>
#g.__next__()#It will trigger the operation of the function body code, then stop when it encounters yield and return the value after yield

res=g.__next__()#The result is: = = > first (stop in case of yield)
print(res)#The results are: 1
res=g.__next__()#The result is: = = = > second (stop when yield is encountered)
print(res)#The result is: 2
res=g.__next__()#The result is: = = = > third (stop when yield is encountered)
print(res)#The result is: 3
res=g.__next__()#The result is: = = > end will also report an error: StopIteration (it can be seen that it will continue to look for yield, but it will exceed the iterator)
```

A generator is an iterator

```g.__iter__
g.__next__
#2. So the generator is an iterator, so you can take this value
res=next(g)
print(res)```

Generator case:

```def dog(name):
print('%s Ready to eat....' % name)
while True:
# x gets the value received by yield
x = yield  # (the default is None)
print('%s Yes%s' % (name, x))

g = dog('xm')
#next(g)#Stop running every time you encounter yield
g.send(None)  # Equivalent to next(g). At the beginning, you can't directly pass other values in g.send(). You need to pass a None first
#It is equivalent to g.next() to the pause position first
g.send('meat')  # Assign a value to yield
g.send('steamed meat bun')#The value passed can be a list
g.close()  # The value cannot be transferred after closing

#The output result is: