目录:
一、迭代器
二、生成器
一、迭代器
我们提一下先提迭代的概念:迭代即为循环遍历,任何遍历的过程都是可以称作迭代。Python中序列、集合、字典、文件和生成器等都是可迭代的,任何可迭代对象都可以作用于for循环。
首先我们来借助最基本的两个内置函数iter() 和 next()
来完成一个简单的迭代器。
a=range(3)
it=iter(a) # 创建迭代器对象
while 1:
print (next(it)) #输出迭代器的下一个元素,迭代器对象从第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
#输出
0
1
2
Traceback (most recent call last):
print (next(it))
StopIteration
我们可以看到触发了StopIteration异常,StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,所以我们做如下改写:
import sys
a=range(3)
it=iter(a) # 创建迭代器对象
while 1:
try:
print (next(it)) #输出迭代器的下一个元素,迭代器对象从第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
except StopIteration: #我们设置在完成循环次后捕获 StopIteration 异常来结束迭代。
sys.exit()
#输出
0
1
2
但,for循环却自带异常处理机制:
a=range(3)
it=iter(a) # 创建迭代器对象
for i in a:
print (next(it))
#输出
0
1
2
类中迭代器的使用
然后我们来拓展一下关于类中的迭代器,之前大家应该也已经留意到了,类中是内置了迭代器的专有方法的。
class Numbers:
def __init__(self,n): #构造函数,获取参数范围,即打印0到几
self.n=n
def __iter__(self): #实例化对象的迭代器创建方法
self.a=0
return self
def __next__(self): #返回迭代器对象下一个元素的方法
if self.a <=self.n:
res=self.a
self.a+=1
return res
else:
raise StopIteration #raise用以引发异常。一旦执行了raise语句,raise后面的语句将不能执行
num=Numbers(3) #实例化对象num
it=iter(num) #创建实例num的迭代器对象it
print(next(it)) #输出迭代器对象it的下一个元素
print(next(it))
print(next(it))
print(next(it))
#输出
0
1
2
3
当然,我们最后的输出完全可以使用for循环将迭代器中的内容读出来,输出相同。
# print(next(it)) #输出迭代器对象it的下一个元素
# print(next(it))
# print(next(it))
# print(next(it))
for i in it:
print(i)
或者使用while循环,不过依然要添加异常处理:
while 1:
try:
print(next(it))
except StopIteration: #使用try-except语句捕捉异常
pass #啥也不想干,占个位
二、生成器
而生成器是一个简单的方式来完成迭代,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
觉得上面的概念太抽象?我们借助实例来解释~几乎所有相关教程都在扯著名的斐波那契数列,我们就不!
说起生成器的创建,常用两种方法,一种是改写列表生成式,一种是使用yield。
列表生成式
列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式,其实我们之前就有在使用了。
a=[x for x in range(10)]
print(a)
#输出
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
顾名思义,它生成了一个列表,那么如何改写为生成器呢?
a=(x for x in range(10))
print(type(a))
#输出
<class 'generator'>
我们可以看到,当前类型已经变为'generator',即生成器类型。改写方法就是将[ ]
替换为( )
。
接下来我们尝试使用一下:
a=(x for x in range(10))
while 1:
try:
print(next(a))
except:
pass
#输出
0
1
2
3
4
5
6
7
8
9
yield
在python中,任何使用了 yield 的函数都被称为生成器(generator)或生成器函数。
def numbers(n): #创建生成器函数,这已经不是一个普通函数啦
for i in range(n):
yield i #在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
num=numbers(3) #调用生成器函数,返回的是一个迭代器对象,即num。
for i in num: #上个例子用的while,这次我们用for
print(i)
#输出
0
1
2
这里往上翻一下,你会发现它与类中迭代器的使用中的例子功能是一致的,但那里用了近20行代码,然而生成器却只用了三行代码,这就是我们为什么说生成器是使用简单的方式进行迭代。
说到底,生成器就是一种特殊的迭代器,这也就是为什么这一章节题目如此简单:《迭代》。
网友评论