Notes on generators and iterators

Keywords: Python

Generators and iterators

generator

Definition: in Python, the mechanism of calculating while looping is called generator.

1. Generator function

Generator functions -- essentially functions written by ourselves

As long as the function containing the yield keyword is a generator function, yield cannot be shared with return and needs to be written in the function

def generator():
    print(a)
    yield 1
ret=generator()
#Generator function: after execution, you will get a generator as the return value
print(ret)
def generator():
     print(1)
     yield 'a'
     print(2)
     yield 'b'
     yield 'c'
 g = generator()
 for i in g:
     print(i)
 ret = g.__next__()
 print(ret)
 ret = g.__next__()
 print(ret)
 ret = g.__next__()
 print(ret)

2. list push to type and dictionary derivation type

List derivation

Syntax [results, for loop condition filtering]

Requirement: each value in the list [0,1,2,3,4,5,6,7,8,9] is required to be increased by 1

Here you can use list generation

lst=[i+1 for i in range(10)]
print(lst)

Dictionary derivation

lst=[11,22,33,44]
dic={i:lst[i] for i in range(len(lst))}
print(dic)

output

{0: 11, 1: 22, 2: 33, 3: 44}

Generator Expressions

g=(x+1 for x in range(10))
print(g)

output

<generator object <genexpr> at 0x00000223B825C890>#Generator memory address

In fact, by changing the list generated [] to (), a generator is created

iterator

l = [1,2,3]
//Indexes
//Loop for
for i in l:
	pass
for k in dic:
    pass
'''list
dic
str
set
tuple'''
f = open()
range()
enumerate
print(dir([]))   #Tell me all the methods the list has
ret = set(dir([]))&set(dir({}))&set(dir(''))&set(dir(range(10)))
print(ret)  #iterable
print('__iter__' in dir(int))
print('__iter__' in dir(bool))
print('__iter__' in dir(list))
print('__iter__' in dir(dict))
print('__iter__' in dir(set))
print('__iter__' in dir(tuple))
print('__iter__' in dir(enumerate([])))
print('__iter__' in dir(range(1)))

As long as the data type can be looped by for, it must have__ iter__ method

print([].__iter__())

A list is executed__ iter__ The return value after () is an iterator

print(dir([]))
print(dir([].__iter__()))
print(set(dir([].__iter__())) - set(dir([])))
print([1,'a','bbb'].__iter__().__length_hint__())  #Number of elements
l = [1,2,3]
iterator = l.__iter__()
print(iterator.__next__())
print(iterator.__next__())
print(iterator.__next__())
print(iterator.__next__())

Iteratable -- > ITER ා as long as it contains__ iter__ Methods are all iterative
[]. iter() iterator -- > next ා you can take values from one iterator through next

As long as it contains__ iter__ All methods are iterative -- iterative protocol

print('__iter__' in dir( [].__iter__()))
print('__next__' in dir( [].__iter__()))
from collections import Iterable
from collections import Iterator
print(isinstance([],Iterator))
print(isinstance([],Iterable))

class A:
	def __iter__(self):
		pass
	def __next__(self):
		pass
a = A()
print(isinstance(a,Iterator))
print(isinstance(a,Iterable))

l = [1,2,3,4]
for i in l.__iter__():
	print(i)

The concept of iterator

Iterator protocol -- internal__ next__ And__ iter__ Method is iterator

Iterator protocol and iterative protocol
All that can be looped for are iterative
It can be iterated inside__ iter__ method
As long as it's an iterator, it can be iterated
The iteratable. iter() method can get an iterator
In iterator__ next__ () method can get values one by one

for loop is actually using iterators
iterator: iteratable object
Give you the memory address directly

print([].__iter__())
print(range(10))

for can only be used when it is an iterative object
When we encounter a new variable and are not sure whether it can be for loop, we will judge whether it can be iterated

for i in l:
	pass
iterator = l.__iter__()
iterator.__next__()

Benefits of iterators:

1. All values will be taken from one container type.

2. Save memory space

#The iterator doesn't take up another chunk of memory,
    #Instead, generate one at a time as the loop
    #Give me one next time
l = [1,2,3,45]
iterator = l.__iter__()
while True:
	print(iterator.__next__())

print(range(100000000000000))
print(range(3))
print(list(range(3)))
def func():
    for i in range(2000000):
        i = 'python%s'%i
    return i
func()

Posted by adrianl on Mon, 22 Jun 2020 00:54:46 -0700