python 迭代器和生成器

mac2022-06-30  117

for循环的本质:循环所有对象,全都是使用迭代器协议。

第一部分

关于为什么要用迭代器:   

优点:

1:迭代器提供了一种不依赖于索引的取值方式,这样就可以遍历那些没有索引的可迭代对象了(字典,集合,文件)

2:迭代器与列表比较,迭代器是惰性计算的,更节省内存

缺点:

1:无法获取迭代器的长度,使用不如列表索引取值灵活2:一次性的,只能往后取值,不能倒着取值用以下例子示例:用索引取字典的内容: d=[1,2,3] i=0 while i < len(d): print(d[i]) i+=1

 其执行结果是:

1 2 3

 用索引取列表的内容:

d=[1,2,3] for i in range(len(d)): print(d[i])

  其执行结果是:

1 2 3

  用迭代器的方法分别取字典的值:

#用迭代器的方式取字典的内容()不依靠索引 d={"a":1,"b":2,"c":3} i=d.__iter__()#生成迭代器 #print(i.__next__())#打印内容 while True: try: print(i.__next__())#打印内容 except StopIteration: break

  其执行结果是:

a b c

  用迭代器的方法取列表里的元素:

#用迭代器的方式取列表的内容()不依靠索引 d=[1,2,3,4,5] i=d.__iter__()#生成迭代器 # print(i.__next__())#打印内容 while True: try: print(i.__next__()) except StopIteration: break

  其执行结果是:

1 2 3 4 5

 总结:

(1)、可迭代的:只要对象本身有__iter__方法,那它就是可迭代的

        d={'a':1,'b':2,'c':3}

        d.__iter__ #iter(d)(表示d是可迭代的)

(2)、执行对象下的__iter__方法,得到的结果就是迭代器

         i=d.__iter__()(i即是迭代器)

(3)3、i.__next__()(即表示的就是执行从字典d里取值)

print(i.__next__()) print(i.__next__()) print(i.__next__())关于迭代器的使用,用以下举例: 用字典示例while循环(由于print(i.__next__())每次输出只能是一个值,但是如果字典里的元素一共有3个,打印4个print(i.__next__())就会报错) #由于print(i.__next__())每次输出只能是一个值,但是如果字典里的元素一共有3个,打印4个print(i.__next__())就会报错,故而使用下列方法可以全部打印且不报错 d={'a':1,'b':2,'c':3} i=iter(d)#即i=d._iter_() while True: try: print(next(i))#即print(i.__next__()) except StopIteration: break

 执行结果是:

a b c

 用列表示例while循环:

l=['a','b','c','d','e'] i=l.__iter__() while True: try: print(next(i))#即print(i.__next__()) except StopIteration: break

 执行结果是:

a b c d e

  

用字典示例:(for循环) d={'a':1,'b':2,'c':3} d.__iter__#代表d是可迭代的 for k in d: #d.__iter__()#取字典里key的值 print(k)

 其执行结果是:

a b c

  

用集合示例(for循环) s={1,2,3,4} s.__iter__()#s是可迭代的 for i in s: print(i)

 执行结果是:

1 2 3 4

 

用文件示例,往文件里写入内容 with open('a.txt','r') as f: f.__iter__()#f是可迭代的 for line in f:#相当于执行的是print(f.__next__)并且不会报错 print(line)

 执行结果是:

aaaaaa bbb cccc eee ffffff

  

关于迭代器,补充的有:

用列表示例,如果列表里有3个元素,故而打印4个print(next(i))会报错 l=[1,2,3] print(len(l)) i=iter(l)#l是可迭代的 print(next(i)) print(next(i)) print(next(i)) print(next(i))

  执行结果是:

3 1 2 3 Traceback (most recent call last): File "C:/Users/Administrator/PycharmProjects/py_fullstack_s4/day23/迭代器.py", line 109, in <module> print(next(i)) StopIteration

 报错原因是: 因为迭代器是一次性的,只能往后取值,不能倒着取值

用列表示例,如果列表里有3个元素,print(next(i))打印3次列表里的元素,则for循环无元素可打印 l=[1,2,3] print(len(l))#输出列表l的长度 i=iter(l)#l是可迭代的 print(next(i)) print(next(i)) print(next(i)) for x in i: print(x)

 执行结果是:

3 1 2 3

  结论:for循环没有进行

用列表示例,如果列表里有3个元素,print(next(i))打印1次列表里的元素,则for循环可打印剩下的2个元素 l=[1,2,3] print(len(l))#输出列表l的长度 i=iter(l)#l是可迭代的 print(next(i)) for x in i: print(x)

 执行结果是:

3#由print(len(l))打印的结果 1 #由print(next(i)打印的结果 2 #由for循环打印的结果 3#由for循环打印的结果

  

 

 第二部分

查看可迭代对象与迭代器对象 通过from collections import Iterable,Iterator来查看分别查看字符串、列表、元组、字典、集合、文件是否是可迭代对象与迭代器对象 s='hello'l=[1,2,3]t=(1,2,3)d={'a':1}set1={1,2,3,4}f=open('a.txt') 示例:查看是否是可迭代对象 s='hello' l=[1,2,3] t=(1,2,3) d={'a':1} set1={1,2,3,4} f=open('a.txt') # 判断是否是可迭代对象,返回Ture是可迭代的 s.__iter__() l.__iter__() t.__iter__() d.__iter__() set1.__iter__() f.__iter__() print(isinstance(s,Iterable)) print(isinstance(l,Iterable)) print(isinstance(t,Iterable)) print(isinstance(d,Iterable)) print(isinstance(set1,Iterable)) print(isinstance(f,Iterable)) # 发现都是可迭代的

 其执行结果是:

True True True True True True

 示例:判断是否是迭代器

# 判断查看是否是迭代器,返回Ture是迭代器 s='hello' l=[1,2,3] t=(1,2,3) d={'a':1} set1={1,2,3,4} f=open('a.txt') print(isinstance(s,Iterator)) print(isinstance(l,Iterator)) print(isinstance(t,Iterator)) print(isinstance(d,Iterator)) print(isinstance(set1,Iterator)) print(isinstance(f,Iterator))

 执行结果是:

False False False False False True

 返回结果是只有文件是迭代器

 

 

 

 

第三部分生成器就是一个函数,这个函数内包含有yield这个关键字关于生成器yield的返回值和函数中return的返回值有何区别:区别是:return只能返回一次函数就彻底结束了,而yield能返回多次值

 

yield到底有何作用:

 

1.yield把函数变成生成器-->迭代器2.用return返回值能返回一次,而yield返回多次3.函数在暂停以及继续下一次运行时的状态是由yield保存示例说明:

 

def countdown(n): print('start coutdown') while n > 0: yield n #有yield将函数变成了生成器 n-=1 g=countdown(5) print(isinstance(g,Iterator))#判断g是一个迭代器 print(g)#返回内存地址 print(next(g)) print(next(g)) print(next(g)) print(next(g)) print(next(g))

 

 执行结果:

 

True <generator object countdown at 0x0000000001E20620> start coutdown 5 4 3 2 1

 

  

 

 

转载于:https://www.cnblogs.com/xuyuanyuan123/p/6694737.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)