生成器生成的数据可以被迭代器迭代
1.生成器:(通过yield把公式变成一个列表,减少列表的内存)
在python中使用了yield的函数被称为生成器(generator)
当一个列表中包含大量元素,一次生成这些元素并保存到列表中将占用大量的内存,通过生成器,根据计算并获取列表中某个元素的值
2.迭代器:字符串 元组 列表等通过iter生成可迭代对象 next进行调用
定义:可以通过next函数不断获取下一个值的对象
补充:return与yield的区别:
return:在程序函数中返回某个值,返回之后函数不再执行,彻底结束:
yield:带有yield函数是一个迭代器,函数返回某个值时,会停留在某个位置,返回函数值后,会在前面停留的位置继续执行,直到程序结束
可以先把yield看成一个return,普通的return返回值之后,程序不会乡下运行。看做return之后再把它看做一个生成器的一部分:示例:
def foo():
print("starting...")
while True:
res = yield 4
print("res:",res)
g = foo()
print(next(g))
print("*"*20)
print(next(g))
输出的结果值为:
starting...
4
********************
res: None
4
生成器:示例:
g = (x*x for x in range(10)) #创建一个生成器对象并赋值个g
print('g的类型为:',type(g))
print(g)
for i in g:
print(i)
#g的类型为: <class 'generator'>
#<generator object <genexpr> at 0x000001D8D5706FC0>
#0 1 4 9 16 25 36 49 64 81
较为复杂的生成元素的方法,不适合用for循环的方式实现,可以用yield实现生成器,例如:实现数字的阶乘:
def faclist(n): #生成器 通过yield result = 1 for i in range(2,n+1): #在2至n范围内依次取值 yield result #遇到yield即暂停执行并返回result,下次执行继续从此处开始 result *=i #将i乘到result上 # print('result = ',result) print(list(faclist(5))) #生成列表 for i in faclist(5): #遍历faclist并输出每个元素的值 遍历生成器是一次一个的调取数据 print(i,end = ' ')#结果值:
#[1, 2, 6, 24]
#1 2 6 24
使用yield实现斐波那契数列:
import sys
def fibonacci(n): # 生成器函数-斐波那契
a, b, counter = 0, 1, 0
while True:
if (counter > n):
return n
yield a
a, b = b, a + b
counter += 1
f = fibonacci(10) # f是一个迭代器,由生成器返回生成
while True:
try:
# ",".join(next(f)) # 空暇在尝试,,此处有一个小bug
print(next(f), end=",")
except StopIteration:
sys.exit()
迭代器:
1.iter函数
迭代器(iterator)是指可以通过next函数不断获取下一个值 (iter创建迭代器,next调用)
可以通过isinstance方法判断一个对象是否为可迭代对象或迭代器
#例如:字符串,列表,元组都可以用于创建迭代器
a = [1,2,3]
it = iter(a) #创建迭代对象
print(next(it)) #输出迭代对象
print(next(it)) #输出迭代对象
for i in a:
print(i)
from collections.abc import Iterable,Iterator
ls = iter([1,2,3,4,5,6]) #创建可迭代对象
g = (x for x in range(1,8)) #创建一个生成器
print('ls是可迭代对象:',isinstance(ls,Iterable))
print('g是可迭代对象:',isinstance(g,Iterable))
print('ls是可迭代器',isinstance(ls,Iterable))
print('g是可迭代器',isinstance(g,Iterable))
while True:
try:
print(next(g))
except StopIteration:
sys.exit()