'''
可迭代对象:
可以直接作用于For循环的对象统称可迭代对象(Iterable)
可以直接作用于for循环的数据类型:
1、集合数据类型,如List、tuple、dict、set、string等
2、generator,包含生成器和带yield的generator function
注意:可以使用isintance()函数判断一个对象是否是Iterable对象
'''
from collections.abc import Iterable
print(isinstance([],Iterable))
print(isinstance({},Iterable))
print(isinstance((),Iterable))
print(isinstance("sunck",Iterable))
print(isinstance(100,Iterable))
print(isinstance((x for x in range(10)),Iterable))
#生成列表
#需求:[1,4,9,16,25,36,49,64,81,100]
#循环比较繁琐
li = []
for i in range(1,11):
li.append(i*i)
print(li)
#列表生成式
li2 = [x * x for x in range(1,11)]
print(li2)
#列表生成式的for循环后可以加判断
li3 = [x for x in range(1,11) if x%2==0]
print(li3)
li4 = [m+n for m in "ABC" for n in "123"]
print(li4)
#生成器:通过列表生成式,可以直接创建一个列表,所有的数据的都会存到内存中,受内存的限制
# 列表中的容量是有限的,如果列表中有10000个数据,如果我们只需要访问前几个元素 ,
# 后面的基本不会访问,那么就会造成内存极大浪费
#如果我们列表中的元素可以按照某种算法推导出来,那么我们在循环遍历列表时不断推导后面的元素,从而节约大量内存
#一边循环一边推导的机制称为生成器(generator)
#创建生成器
#1、修改列表生成式:将列表生成式的[]改为()即可
g = (x for x in range(1,11))
print(g)
print(type(g))
#生成器特点:可以通过next函数得generator的下一个值
print(next(g))
print(next(g))
#当所有元素都遍历完了后,再执行next会有StopIteration异常
'''
推导算法比较复杂,用列表生成父for循环无法实现的时候可以选择使用函数生成器
如果需要将一个函数变为生成器函数,只需要将函数return改为yield
编程generator函数,在每次调用next()的时候,遇到yield语句返回,如果再次执行next()
会从上次返回的yield语句处继续执行
'''
def func():
yield 0
print("sunck is a good man")
yield 3
print("sunck is a nice man")
yield 2
print("sunck is a cool man")
yield 1
res = func()
print(res)
print(type(res))
ret = next(res)
print(ret)
print(next(res))
print(next(res))
print(next(res))
#编写斐波拉契数列。
def fib(count):
index = 0
x,y = 0 ,1
while index < count:
yield y
x,y = y,x+y
index += 1
return "sunck is a good man"
g = fib(6)
#for i in g:
# print(i)
#for循环变量genertaor,拿不到return和generator的返回值,如果想拿返回值,需要捕获
#StopIteration错误,返回值包含在错误对象的value属性中
while(1):
try:
ret=next(g)
print(ret)
except StopIteration as e:
print("返回值:",e.value)
break