Python 迭代器
概述:
迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
延迟计算或惰性求值 (Lazy evaluation)
迭代器不要求你事先准备好整个迭代过程中所有的元素。仅仅是在迭代至某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合。
可迭代对象
迭代器提供了一个统一的访问集合的接口。只要是实现了__iter__()或__getitem__()方法的对象,就可以使用迭代器进行访问。
序列:字符串、列表、元组
非序列:字典、文件
自定义类:用户自定义的类实现了__iter__()或__getitem__()方法的对象
判断该数据是否可迭代?
迭代器的数据类型: 一类是集合数据类型,如 list 、 tuple 、 dict 、 set 、 str 等; 一类是 generator ,包括生成器和带 yield 的generator function。 这些可以直接作用于 for 循环的对象统称为可迭代对象: Iterable 。 ''' #判断isinstance()是否可以迭代Iterable from collections import Iterable print('{}:',isinstance({},Iterable)) print('[]:',isinstance([],Iterable)) print("'':",isinstance('',Iterable)) print('():',isinstance((),Iterable)) """ Iterable:显示结果 {}: True []: True '': True (): True 而生成器不但可以作用于 for 循环, 还可以被 next() 函数不断调用并返回下一个值, 直到最后抛出 StopIteration 错误表示无法继续返回下一个值了。 """
创建迭代器对象:
li = [1, 2, 3, 4] res = li.__iter__() print(res.__next__()) print(res.__next__()) print(res.__next__()) print(res.__next__()) #print(res.__next__())#StopIteration 没有就报错 li = [1, 2, 3, 4] for i in li: #iter = li.__iter__() iter.__next__() print(li)# iter.__next__() ---> print(iter.__next__() ) 为:1 #print(iter.__next__() ) 为:2 #print(iter.__next__() ) 为:3 #print(iter.__next__() ) 为:4 #print(iter.__next__() ) 不存在时会报错并且,用其它语句处理错误 #for 循环是基于迭代器 #集合 dic = {1, 3, 2} for q in dic: print(q) iter_s= dic.__iter__() print(iter_s) #<set_iterator object at 0x0000026DBEC47E10> print(iter_s.__next__()) print(iter_s.__next__()) print(iter_s.__next__())
for循环遍历迭代器经常为我们做两件事:
""" for 循环的工作机制 第一步:使用每个数据内置的__iter__() 第二步:在使用迭代器协议 __next__() 方法 """ # 字典 dic1 = {'name':'age','age': 23} iter_s = dic1.__iter__() print(iter_s.__next__()) print(iter_s.__next__()) f = open('open.txt','r+') iter_s = f.__iter__() print(iter_s.__next__()) print(iter_s.__next__()) """ 为什么要使用迭代器了? 答案:因为迭代器有__next__()方法 ,需要用数据时,很简单一下__next__()方法, 就能够获取一个值,不会占太多的内存(迭代器的优点:剩内存空间) 为什么所有的数据都用”for循环遍历“? 答案:for循环就是基于迭代器协议,提供了一个统一的可以遍历所有对象的方法,即遍历之前,先调用 对象的__iter__()方法将其转换成一个迭代器,然后使用迭代器其协议去实现循环访问,这样所有的对象 就都可以通过for循环来遍历,而且你看到效果确实如此 """
可迭代对象
迭代器提供了一个统一的访问集合的接口。只要是实现了__iter__()或__getitem__()方法的对象,就可以使用迭代器进行访问。
序列:字符串、列表、元组
非序列:字典、文件
自定义类:用户自定义的类实现了__iter__()或__getitem__()方法的对象