概念
Python生成器是一种特殊的函数,它可以在需要时生成一个序列的值。与普通函数不同,生成器函数使用yield语句或生成器表达式(也叫生成器推导式)来产生值,并且可以暂停和恢复执行。生成器可以逐个生成值,而不是一次性生成整个序列,这样可以节省内存并提高性能。
一般与循环语句(for、while)、next函数等结合使用
生成器在处理大量数据或无限序列时非常有用,可以节省内存和提高性能。
它们还可以用于创建可迭代的对象,并且可以通过for循环来遍历。
生成器表达式可以简化代码,特别是在需要生成复杂序列时。
生成器可以通过两种方式创建:生成器函数和生成器表达式。
生成器函数(yield关键字的应用)
生成器函数是一种使用yield语句的函数即函数中出现了yield关键字,就表示此函数是生成器函数。
当函数被调用时,它返回一个生成器对象,可以使用next()函数来逐个获取生成器中的值。
每次执行到yield语句时,函数会暂停执行并返回一个值给调用方。
当再次调用next()函数时,函数会从上次离开的地方继续执行,直到遇到下一个yield语句。
def my_generator(): yield 1 yield 2 yield 3 gen = my_generator() print(type(gen)) # <class 'generator'> print(next(gen)) # 输出: 1 print(next(gen)) # 输出: 2 print(next(gen)) # 输出: 3
生成器表达式也叫生成器推导式
生成器表达式是一种类似于列表推导式的语法,但使用圆括号而不是方括号。
它们可以在创建生成器时非常方便,因为它们不需要一次性生成整个序列。生成器表达式可以通过迭代来访问生成器中的值。
1 ''' 2 生成器表达式也叫生成器推导式。是一种类似于列表推导式的语法,但使用圆括号而不是方括号。 3 它们在创建生成器时非常方便,因为它们不需要一次性生成整个序列。生成器表达式可以通过迭代来访问生成器中的值。 4 5 6 ''' 7 8 # 1. 定义生成器 9 gen = (x for x in range(1, 4)) 10 print(type(gen)) # <class 'generator'> 11 # 2. 一般与循环、next函数等结合使用 12 print(next(gen)) # 输出: 1 13 print(next(gen)) # 输出: 2 14 print(next(gen)) # 输出: 3
生成器的特点
1. 惰性机制
2. 只能向前
3. 节省内存
在代码中的体现:
1. 生成器代码执行到yield会返回结果,下次启动生成器会从暂停位置继续向下执行
2. 生成器把数据全部生成完成,再向下执行会抛出StopIteration异常
3. while循环需要手动处理异常
4. for循环内部自动回处理异常
1 def my_generator(): 2 yield 1 3 yield 2 4 yield 3 5 6 7 gen = my_generator() 8 ''' 9 输出: 10 Traceback (most recent call last): 11 File "D:\allen_class\python\base\base\043生成器\03异常.py", line 10, in <module> 12 print(next(gen)) 13 ^^^^^^^^^ 14 StopIteration 15 1 16 2 17 3 18 ''' 19 while True: 20 print(next(gen)) # 会抛异常
1 def my_generator(): 2 yield 1 3 yield 2 4 yield 3 5 6 gen = my_generator() 7 8 try: 9 while True: 10 value = next(gen) 11 print(value) 12 except StopIteration: 13 pass 14 15 # Output: 1 2 3
1 ''' 2 for循环不会触发StopIteration异常 3 ''' 4 5 6 def my_generator(): 7 yield 1 8 yield 2 9 yield 3 10 11 12 ''' 13 输出: 14 1 15 2 16 3 17 ''' 18 gen = my_generator() 19 for i in gen: 20 print(i)
生成器的最佳实践
- 使用生成器来处理大量数据或无限序列,以避免一次性加载整个序列到内存中;
- 使用生成器函数和yield语句来编写可迭代的对象,并且可以通过for循环来遍历它们;
- 使用生成器表达式来简化代码,特别是在需要生成较复杂的序列时。
典型示例:斐波那契数列
什么是斐波那契数列(Fibonacci sequence)?
又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称“兔子数列”。
其数值为:1、1、2、3、5、8、13、21、34……在数学上,这一数列以如下递推的方法定义:
F(0)=1,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)。这个数列从第三项开始,每一项都等于前两项之和
示例
1 # 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 2 def fb(num): 3 a = 0 4 b = 1 5 6 # 记录生成了几个数字 7 index = 0 8 9 while index < num: 10 print(f"index={index}") 11 result = a 12 a, b = b, a + b 13 print(f"index={index},result={result}") 14 yield result 15 index += 1 16 17 18 gen = fb(5) 19 # 以下语句,可以验证生成器只能往下走,不能回头 20 # print(next(gen)) # 0 21 # print(next(gen)) # 1 22 for i in gen: 23 print(i)
输出:
index=0 index=0,result=0 0 index=1 index=1,result=1 1 index=2 index=2,result=1 1 index=3 index=3,result=2 2 index=4 index=4,result=3 3
标签:index,生成器,yield,next,print,gen From: https://www.cnblogs.com/allenxx/p/17666089.html