# 迭代器
# 1,什么事迭代器
# 迭代指的是一个重复的过程,每一次重复都是基于上一次的结果而来的
# 迭代器指的是迭代取值的工具,该工具的特点是可以不依赖索引取值
# while True:
# print('-------->') #这是单纯的重复
# l=['alex','blex','clex','dlex']
# count = 0
# while count<len(l):
# print(l[count])
# count+=1
# 2,为何要用迭代器
# 就是为了找出一种通用的不依赖索引取值迭代取值方式
# 3,如何用迭代器
# 可迭代的对象:在python中但凡内置有.__iter__方法的对象,都称之为可迭代的对象
# (字符串,列表,元组,字典,集合,文件)
# x='hello'
# x.__iter__()
#
# l=['alex','blex','clex','dlex']
# l.__iter__()
#
# t=('alex','blex','clex','dlex')
# t.__iter__()
#
# dic={'name':'zrg','age':24,'sex':'male'}
# dic.__iter__()
#
# pythons = {'alex','blex','clex','dlex'}
# pythons.__iter__()
#
# f=open(r'a.txt',mode='rt',encoding='utf-8')
# f.__iter__()
# f.close()
# 迭代器对象:既内置有.__iter__方法又内置有.__next__方法
# (文件)
# 可迭代对象可以转换成迭代器对象:调用可迭代对象的内置.__iter__方法会有一个返回值,该返回值就是迭代器对象
# l=['alex','blex','clex','dlex']
# iter_l=l.__iter__()
# res1=iter_l.__next__()
# print(res1) #alex
# res2=iter_l.__next__()
# print(res2) #blex
# while True:
# try:
# print(iter_l.__next__())
# except StopIteration:
# break
"""
alex
blex
clex
dlex
"""
# while True:
# try:
# print(next(iter_l))
# except StopIteration:
# break
# class Fibs:
# def __init__(self):
# self.a=0
# self.b=1
# def __int__(self):
# self.a = 0
# 如果取值取干净了,会报异常
# dic={'name':'zrg','age':24,'sex':'male'}
# iter_dic=dic.__iter__()
# while True:
# try:
# print(iter_dic.__next__())
# except StopIteration:
# break
# f=open(r'D:zrgday12作业.py',mode='rt',encoding='utf-8')
# while True:
# try:
# print(f.__next__())
# except StopIteration:
# break
#
# f.close()
# for 循环:迭代器循环
# 工作原理:
# info = {'name':'zrg','age':18,'is_beautiful':True,'sex':'male'}
# for k in info: # for循环对象会将in后面的对象变成迭代器对象(in后跟的一定要是可迭代对象)
# in 后跟的可迭代对象会在for循环开始自动调用可迭代对象的__iter__方法,会拿到一个迭代器对象
# 然后for循环,next一次取一次值给k,然后执行一次循环体代码,next一次取一次值给k,然后再执行一次循环体代码,直到取干净,for循环自动检测到异常,捕捉到异常之后结束循环
# print(k)
# 总结迭代器
# 优点:
# 1,提供了一种通用的可以不依赖索引的取值方式
# 2,同一时刻的内存中只有一个值,更加节省空间
# 缺点:
# 1,取指定的值不如索引灵活,并且迭代器是一次性的
# 2,无法预知迭代器数据的个数
# 关于迭代器
# 调用可迭代对象的__iter__会得到一个迭代器对象
# 调用迭代器对象的__next__得到的是迭代器的下一个值
# 调用迭代器对象的__iter__得到的会是迭代器本身
# dic=iter({'name':'zrg','age':24,'sex':'male'})
# while True:
# try:
# print(next(dic))
# except StopIteration:
# break
# 从迭代器创建序列
class TestIterator:
value = 0
def __next__(self):
self.value+=1
if self.value>10:raise StopIteration
return self.value
def __iter__(self):
return self
ti=TestIterator()
print(list(ti))
# 使用构造函数list显示的将迭代器转换成列表
# dic = {'x':1,'a':3,'y':2,'b':4}
#
# iter_dic=dic.__iter__()
# res=iter_dic.__next__()
# print(res)
# s='hello'
# print(list(s))
# dic = {'x':1,'a':3,'y':2,'b':4}
# for k,v in dic.items():
# print(k,v)
# print(dic.items())
# 注意
# dic = {'x','a','y','b'}
# iter_dic=iter(dic)
#
# l1=list(iter_dic)
# print(l1)
#
# l2=list(iter_dic)
# print(l2)
# 同一个迭代器取值只能取一次
dic = {'x','a','y','b'}
print(list(dic))
print(list(dic))
print(list(dic))
print(list(dic))
print(list(dic))
# 基于可迭代对象不同的在造不同的迭代器
# 生成器
# 什么是生成器:
# 在函数内但凡出现yiel关键字,再调用函数就不会执行函数体代码,会返回一个值,该值称之为生成器
# 生成器本质就是迭代器
# def func():
# print('----第一次----')
# yield 1 #暂停
# print('----第二次----')
# yield 2
# print('----第三次----')
# yield 3
# print('----第四次----')
# func()#什么代码也不执行
# g=func() # 会返回一个值
# print(g) #<generator object func at 0x000001A8D6E00E60>
# g.__iter__()
# g.__next__()
# 生成器
# 为什么要有生成器
# 生成器是一种自定义迭代器的方式
# next(g) #----第一次----
# res1=next(g)
# print('第一次的返回值:',res1)
#
# print('.'*100)
# res2=next(g)
# print('第二次的返回值:',res2)
#
# res3=next(g)
# print('第三次的返回值:',res3)
#
# res4=next(g)
# print('第四次的返回值:',res4)
# for item in g:
# pass
# """
# ----第一次----
# ----第二次----
# ----第三次----
# ----第四次----"""
# l=range(1,100,2)
# for i in l:
# print(i)
def my_range(start,stop,step):
while stop>start:
yield start
start += step
res=my_range(1,100,2)
for i in res:
print(i)
# print(next(res))
# print(next(res))
# print(next(res))
# 递归式生成器
# def flatten(nested):
# try:
# for sublist in nested:
# for element in flatten(sublist):
# yield element
# except TypeError:
# yield nested
#
# nested = [[[1],2],3,4,[5,[6,7]],8]
# res=flatten(nested)
# for num in res:
# print(num)
# res=list(flatten([[[1],2],3,4,[5,[6,7]],8]))
# print(res)
# 如果nested是字符串或者类是字符串的对象,他就属于序列。
def flatten(nested):
try:
try:nested+''
except TypeError:pass
else:raise TypeError
for sublist in nested:
for element in flatten(sublist):
yield element
except TypeError:
yield nested
# 生成器是包含关键字yield的函数,但被调用时不会执行函数体的代码,而是返回一个迭代器。
# 每次请求值时,都执行生成器的代码,直到遇到yield或retuan。
# yield意味着应生成一个值,而return意味着生成器应停止执行(既不在生成值,仅当在生成器调用return时,才能不提供任何参数)
# 简而言之,生成器有两个单独的部分组成:生成器的函数和生成器的迭代器。
# 生成器的函数有def语句组成,其中包含yield。
# 生成器的迭代器是这个函数返回的结果。
def simple_generator():
yield 1
print(simple_generator)
#<function simple_generator at 0x000001CD6C5C1E18>
print(simple_generator())
#<generator object simple_generator at 0x000001709B1E0E08>