一、什么叫生成器?
在Python
中,一边循环一边计算的机制,称为生成器:generator
二、怎么创建生成器
1.生成器表达式()
生成器表达式返回一个生成器对象,需要用一个变量名来接收
g = (x*3 for x in range(5))
# 打印g,返回一个生成器对象
print(g) # <generator object <genexpr> at 0x000002125FA1DA50>
2.生成器函数
def generation():
print('hello1')
yield 1
print('hello2')
yield 2
print('hello3')
yield 3
gg = generation()
# 打印gg,返回一个生成器对象
print(gg) # <generator object generation at 0x000002125FA1D740> :函数未立即执行,返回一个生成器对象
next(gg) # 返回hello1, 调用next(gg)或gg.next()方法函数执行,遇到‘yield’函数执行停止
next(gg) # 返回hello2, 调用next(gg)或gg.next()方法函数执行,遇到‘yield’函数执行停止
next(gg) # 返回hello3, 调用next(gg)或gg.next()方法函数执行,遇到‘yield’函数执行停止
next(gg) # 返回StopIteration
说明:从上面可以看到‘generation’函数没有使用return作为返回值,而是使用了yield作为返回值。
一个带有yield作为返回值的函数为生成器函数。当我们使用yield时,它帮我们自动创建了__iter__()
和next()方法,在没有数据时,会抛出stopIteration异常。
简述函数执行过程:
a.调用函数generation(),返回一个生成器对象
b.第1次使用next(gg),函数开始执行,返回hello1,遇到yield关键字,函数停止执行,并记录当时执行的位置'1'
c.第2次使用next(gg),函数从'1'处,开始执行,返回hello2,遇到yield关键字,函数停止执行,并记录当时执行的位置'2'
d.第3次使用next(gg),函数从'2'处,开始执行,返回hello3,遇到yield关键字,函数停止执行,并记录当时执行的位置'3'
e.第4次使用next(gg),函数从'3'处,开始执行,但是3后面没有语句了此时会抛出异常‘StopIteration’
从上面可以看到写4个next(gg),可不可以不写这么多?
答:可以,可以用for循环来代替
for i in gg:
print(i)
# i的返回值,当使用for循环对迭代器对象进行循环时,会返回yield的返回值
hello1
1
hello2
2
hello3
3
三、什么叫迭代器?
在 Python 中,迭代器是实现迭代器协议的对象,它包含方法 __iter__()
和 __next__()
创建迭代器
要把对象/类创建为迭代器,必须为对象实现 __iter__()
和 __next__()
方法。
正如 Python 类/对象 ,所有类都有名为 __init__()
的函数,它允许您在创建对象时进行一些初始化。
__iter__()
方法的初始化迭代器对象。
__next__()
方法进行迭代
class MyNumbers:
def __iter__(self):
self.a = 1 # 初始化
return self # 返回迭代器对象本身
def __next__(self):
x = self.a
self.a += 1 # 迭代
return x
myclass = MyNumbers() # 实例化对象,创建命名空间
myiter = iter(myclass) # 使用iter方法进行迭代
print(next(myiter)) # 1
print(next(myiter)) # 2
print(next(myiter)) # 3
print(next(myiter)) # 4
print(next(myiter)) # 5
Python 迭代器的好处
使用迭代器的好处是可以节省资源。
-
代码减少。
-
代码冗余得到极大解决。
-
降低代码复杂度。
-
它为编码带来了更多的稳定性。
四、可迭代对象
可以实现iter方法,可以用for…in…进行遍历的对象
可以使用python内置数isinstance()来判断一个对象是否属于可迭代对象
from typing import Iterable
# 列表
a = isinstance([1, 2, 3], Iterable)
print(a) # True
# 字符串
b = isinstance('1', Iterable)
print(b) # True
# 整数
c = isinstance(1, Iterable)
print(c) # False
# 元组
d = isinstance((1, 2, 3), Iterable)
print(d) # True
# 字典
e = isinstance({'name': 'anna'}, Iterable)
print(e) # True
# 集合
f = isinstance({'age'}, Iterable)
print(f) # True
列表、字符串、元组、字典、集合都是可迭代对象,而整数不是可迭代对象
注意:可迭代对象不是迭代器
下面将可迭代对象转化为迭代器
from typing import Iterable, Iterator
l1 = ['name', 'age', 'sex']
a = isinstance(l1, Iterable) # 判断对象是否为可迭代对象
aa = isinstance(l1, Iterator) # 判断对象是否为迭代器
print(a) # True
print(aa) # False
'''
根据迭代器定义,迭代器使用__iter__()方法初始化迭代器对象,使用__next__()方法进行迭代;
而可迭代对象只实现了__iter__()方法,但是没有实现__next__()方法,所以不是迭代器
'''
可以使用iter()方法将可迭代对象转化为迭代器
iterator_a = iter(l1)
print(type(iterator_a),isinstance(iterator_a, Iterator)) # <class 'list_iterator'> , True
结论:每个迭代器都是可一迭代的,可以迭代的对象不一定是迭代器
标签:__,迭代,python,生成器,next,gg,print,浅析 From: https://www.cnblogs.com/zy7941246/p/17332300.html