#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 学习网站:www.liaoxuefeng.com
#****************************************************
# Python3 高级特性-生成器 *
#****************************************************
print ("--------------------分割线------------------")
#============
# 生成器
#============
'''
通过列表生成式,可以直接创建一个列表。但受内存限制,列表容量有限,而且
创建百万级元素的列表,不仅占用存储空间,如果只访问前几个元素,后面
元素占用的空间会白白浪费。
列表元素可以按照某种算法推算出来,在循环的过程中不断推算出后续的元素
这样就不必创建完整的list,节省大量的空间,这种一边循环一边计算的机制
称为生成器:generator。
'''
# 创建generator方法一:把列表生成式的[]改成()
list_a = [x*x for x in range(5)]
print( list_a ) # [0, 1, 4, 9, 16]
gen_a = (x*x for x in range(5))
print( gen_a )
# <generator object <genexpr> at 0x000002174EE158E0>
# 通过next()函数获得generator的下一个返回值,每次调用next(gen_a),就
# 计算出gen_a的下一个元素的值,直到最后一个值,没有更多元素则抛出
# StopIteration的错误
print( next(gen_a),next(gen_a) ) # 0 1
# 通常使用for循环获取generator元素
gen_b = (x*x for x in range(5))
for n in gen_b:
print(n, end=' ') # 0 1 4 9 16
print()
print ("--------------------分割线------------------")
# 如推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候
# 还可以用函数来实现。
# 例:普通函数斐波那契数列 1, 1, 2, 3, 5, 8, 13,...
def fib(max):
n, a, b = 0, 0, 1
while n < max:
print( b,end=' ' )
a, b = b, a+b
n = n + 1
return 'done'
print( fib(7) ) # 1 1 2 3 5 8 13 done
# fib函数实际上定义了斐波那契数列的推算规则,把fib函数变成generator
# 只需要把print(b)改为yield b,这也是定义generator的另一种方法。
# 重新定义fib1函数,变为generator
def fib1(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a+b
n = n + 1
return 'done'
print( fib1(5) )
# <generator object fib1 at 0x0000014483FB5990>
aa = fib1(3)
print( next(aa),next(aa),next(aa) ) # 1 1 2
'''
generator与函数的执行流程不一样。函数是顺序执行,遇到return语句或者
最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候
执行,遇到yield语句返回,再次执行时,从上次返回的yield语句处继续执行。
'''
'''
在fib1循环过程中,必须要给循环设置一个条件退出循环,例如n<max,不然
就会产生一个无限数列出来。
函数变为generator后,基本不会用next()来获取下一个返回值,而是直接使用
for循环来迭代。
'''
for n in fib1(3):
print(n, end=' ') # 1 1 2
print()
print ("--------------------分割线------------------")
'''
上面for循环调用generator时,发现拿不到generator的return语句的返回值
如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在
StopIteration的value中。
'''
gen_c = fib1(5)
while True:
try:
x = next(gen_c)
print('gen_c',x)
except StopIteration as e:
print('Generator return value:', e.value)
break
'''
执行结果:
gen_c 1
gen_c 1
gen_c 2
gen_c 3
gen_c 5
Generator return value: done
'''
'''
小结:
可以简单地把列表生成式改成generator,也可以通过函数实现复杂逻辑的generator
generator工作原理:它是在for循环的过程中不断计算出下一个元素,并在适当
的条件结束for循环。对于函数改成的generator来说,遇到return语句或这执行到
函数体最后一行语句,就是结束generator的指令,for循环随之结束。
'''
# 杨辉三角:
def triangles(max):
list_x = [1]
y = 1
while y < max :
yield list_x
list_x = [1] + [ list_x[n] + list_x[n+1] for n in \
range(len(list_x)-1) ] + [1]
y = y + 1
for n in triangles(8):
print( n )
'''
执行结果:
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
'''
Python3 学习笔记17_高级特性(生成器)_20180307
最新推荐文章于 2025-06-25 22:18:48 发布
本文介绍Python中的生成器概念,包括其基本用法、如何通过列表生成式创建生成器及使用函数定义复杂逻辑的生成器。此外,还探讨了生成器的工作原理及如何正确处理生成器的返回值。
3082

被折叠的 条评论
为什么被折叠?



