python基础-迭代器和生成器

一、递归和迭代

1、递归:(问路示例)

递归算法是一种直接或者间接地调用自身算法的过程。在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。

2、迭代:简单理解为更新换代( 儿子生孙子的故事)

二、迭代器协议

1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退)

2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法)

3.协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象。

4、for循环的本质就是遵循迭代器协议去访问对象,那么for循环的对象肯定都是迭代器。

5、不可迭代对象:字符串,列表,元组,字典,集合,文件对象。只不过通过for循环,调用了他们内部的__iter__方法,把他们变成了可迭代对象。

特点:

  1. 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
  2. 不能随机访问集合中的某个值,只能从头到尾依次访问
  3. 访问时只能往后走,不能往前退
  4. 便于循环比较大的数据集合,节省内存

三、迭代器

ps1:

   1、遵循迭代器协议访问方式

 1 x=‘hello‘
 2 # print(dir(x))
 3 iter_test=x.__iter__()
 4
 5 print(iter_test)
 6 print(iter_test.__next__())  #获取第1个值
 7 print(iter_test.__next__())  #获取第2个值
 8 print(iter_test.__next__())  #获取第3个值
 9 print(iter_test.__next__())  #获取第4个值
10 print(iter_test.__next__())  #获取第5个值
11 print(iter_test.__next__())  #超出边界,当for循环结束时,捕捉到StopIteration异常,他就会终止迭代
执行结果:
1 Traceback (most recent call last):
2 h
3   File "D:/python/day9/iter和yield.py", line 14, in <module>
4 e
5     print(iter_test.__next__())  #超出边界,当for循环结束时,捕捉到StopIteration异常,终止迭代
6 l
7 StopIteration
8 l
9 o

ps2:

2、for循环访问方式

for循环l本质就是遵循迭代器协议的访问方式,先调用diedai_l=l.__iter__()方法,或者直接diedai_l=iter(l),然后依次执行diedai_l.next(),直到for循环捕捉到StopIteration终止循环
 

#for循环所有对象的本质都是一样的原理。

1 l=[1,2,3]
2 for i in l:  #把列表变成i_l=l.__iter_() ,再执行他下面的i_l.__next__()
3     print(i)

执行结果:

1 1
2 2
3 3

ps3:

3、用索引的方式,遍历列表的值

1 l=[1,2,3]
2
3 index=0
4 while index < len(l):
5     print(l[index])
6     index += 1

执行结果:

1 1
2 2
3 3

ps4:

用迭代器的方式

1 l=[1,2,3]
2 iter_l=l.__iter__()       #遵循迭代器协议,生成可迭代对象
3 print(iter_l.__next__())  #取列表的值
4 print(iter_l.__next__())  #取列表的值
5 print(iter_l.__next__())  #取列表的值

执行结果:

1 1
2 2
3 3

ps5:

用for循环的方式

1 l=[1,2,3]
2 for i in l:
3     print(i)

执行结果:

1 1
2 2
3 3

ps6:

集合的方式

方法一:

1 #集合的方式
2 s={1,2,3}
3 for i in s:
4     print(i)

方法二:

1 s={1,2,3}
2 iter_s=s.__iter__()    #通过iter方法
3 print(iter_s)
4 print(iter_s.__next__())   #调用next
5 print(iter_s.__next__())
6 print(iter_s.__next__())
7 print(iter_s.__next__())  #超出边界,当for循环结束时,捕捉到StopIteration异常,终止迭代

执行结果:

1 <set_iterator object at 0x00BF4198>
2 Traceback (most recent call last):
3 1
4   File "D:/python/day9/iter and yield.py", line 46, in <module>
5 2
6     print(iter_s.__next__())  #超出边界,当for循环结束时,捕捉到StopIteration异常,终止迭代
7 3
8 StopIteration

ps7:

字典的方式

1 #字典的方式
2 dic={‘a‘:1,‘b‘:2}
3 iter_d=dic.__iter__()
4 print(iter_d.__next__())
5 print(iter_d.__next__())
6 print(iter_d.__next__())

ps8:

文件的方式

1、创建一个test.txt文件,内容如下:

1 111111
2 222222
3 333333

2、执行下面代码

1 #文件的方式
2 f=open(‘test.txt‘,‘r+‘)
3 #for i in f:
4 iter_f=f.__iter__()   #遵循可迭代原则,转换成迭代器,要的时候拿到内存,可以节约内存空间
5 print(iter_f)
6 print(iter_f.__next__(),end=‘‘)  #第一行
7 print(iter_f.__next__(),end=‘‘)  #第二行
8 print(iter_f.__next__(),end=‘‘)  #第三行
9 print(iter_f.__next__(),end=‘‘)  #执行完了的时候,就捕捉到StopIteration异常,终止迭代

执行结果:

1 <_io.TextIOWrapper name=‘test.txt‘ mode=‘r+‘ encoding=‘cp936‘>
2 Traceback (most recent call last):
3 111111
4   File "D:/python/day9/iter and yield.py", line 64, in <module>
5 222222
6     print(iter_f.__next__(),end=‘‘)
7 333333StopIteration    #执行完了的时候,就捕捉到StopIteration异常,终止迭代

ps9:

用while去模拟for循环做的事情,实现迭代器的过程

1 l=[1,2,3,4,5]
2 diedai_l=l.__iter__()
3 while True:
4     try:
5         print(diedai_l.__next__())
6     except StopIteration:
7         # print(‘迭代完毕了,循环终止了‘)
8         break   #直接break,捕捉到导常,就不会报StopIteration异常

执行结果:

1 1
2 2
3 3
4 4
5 5

迭代器总结

1 l=[‘die‘,‘erzi‘,‘sunzi‘,‘chongsunzi‘]   #把所有结果都放在内存中,比较占用内存
2
3 iter_l=l.__iter__()        #转成迭代器形式,可以在任意位置传输(也叫可迭代对象)
4 print(iter_l)
5 print(iter_l.__next__())    #第一次调用,得到的结果:die
6 print(iter_l.__next__())    #第二次调用, 得到的结果:erzi
7 print(iter_l.__next__())    #第三次调用, 得到的结果:sunzi
8 print(iter_l.__next__())    #第四次调用, 得到的结果:chongsunzi
9 print(iter_l.__next__())    #超出边界,捕捉到StopIteration异常,终止迭代

补充:

next内置函数

说明:next内置函数的next()方法,就是在调用l.__iter__(),下的 __next__()方法

1 l=[‘die‘,‘erzi‘,‘sunzi‘,‘chongsunzi‘]
2 iter_l = l.__iter__()
3 print(next(iter_l))        #next()---->iter_l.__next__()
4 print(next(iter_l))
5 print(next(iter_l))
6 print(next(iter_l))

执行结果:

1 die
2 erzi
3 sunzi
4 chongsunzi


生成器(详细讲解)

一、什么是生成器?

生成器就是迭代器,可以理解为一种数据类型,这种类型自动实现了迭代器协议.(其他的数据类型需要调用自己内置的__iter__方法),所以生成器就是可迭代对象。

二、生成器分类及在python中的表现形式?(Python有两种不同的方式提供生成器)

1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行

2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表

三、使用生成器的优点:

Python使用生成器对延迟操作提供了支持。所谓延迟操作,是指在需要的时候才产生结果,而不是立即产生结果。这也是生成器的主要好处。

四、生成器小结:

1.是可迭代对象

2.实现了延迟计算,省内存啊

3.生成器本质和其他的数据类型一样,都是实现了迭代器协议,只不过生成器附加了一个延迟计算省内存的好处,其余的可迭代对象可没有这点好处。

五、生成器(yield )示例:

1 def test():
2     yield 1    #只要有yield就是生成器
3     yield 2    #他可以yield多次
4     yield 3
5 g=test()
6 print(‘来自函数‘,g)
7 print(g.__next__())   #生成器自动实现了迭成器,所以会有__next__()方法。
8 print(g.__next__())
9 print(g.__next__())

执行结果:

1 来自函数 <generator object(迭代器对象) test at 0x01B0BAE0>
2 1
3 2
4 3

六、补充知识:

三元表达式

1 #三元表达式演变过程
2
3 # name=‘alex‘
4 # ‘SB‘ if name == ‘alex‘ else ‘帅哥‘  #if判断name=alex就,返回SB;如果不等于alex,就返回帅哥。但SB要写在最前面。

七、三元表达式完整写法

if判断name=alex就,返回SB;如果不等于alex,就返回帅哥。但SB要写在最前面。

1 name=‘alex‘
2 name=‘linhaifeng‘
3 res=‘SB‘ if name == ‘alex‘ else ‘帅哥‘  #三元表达式
4 print(res)

执行结果:

1 帅哥

 八、生成器表达式和列表解析

ps1:

生成一个列表

1 egg_list=[]
2 for i in range(10):
3     egg_list.append(‘鸡蛋%s‘ %i)
4 print(egg_list)

执行结果:

1 [‘鸡蛋0‘, ‘鸡蛋1‘, ‘鸡蛋2‘, ‘鸡蛋3‘, ‘鸡蛋4‘, ‘鸡蛋5‘, ‘鸡蛋6‘, ‘鸡蛋7‘, ‘鸡蛋8‘, ‘鸡蛋9‘]

ps2:

列表解析方法(生成列表)

1 l=[‘鸡蛋%s‘ %i for i in range(10)]
2 print(l)

执行结果:

1 [‘鸡蛋0‘, ‘鸡蛋1‘, ‘鸡蛋2‘, ‘鸡蛋3‘, ‘鸡蛋4‘, ‘鸡蛋5‘, ‘鸡蛋6‘, ‘鸡蛋7‘, ‘鸡蛋8‘, ‘鸡蛋9‘]

ps3:

三元表达式方法(生成列表)

1 #鸡蛋>5
2 l1=[‘鸡蛋%s‘ %i for i in range(10) if i > 5 ]
3 # l1=[‘鸡蛋%s‘ %i for i in range(10) if i > 5 else i] #没有四元表达式
4 print(l1)
5
6 #鸡蛋<5
7 l2=[‘鸡蛋%s‘ %i for i in range(10) if i < 5]
8 print(l2)

执行结果:

1 #鸡蛋>5结果:
2 [‘鸡蛋6‘, ‘鸡蛋7‘, ‘鸡蛋8‘, ‘鸡蛋9‘]
3
4 #鸡蛋<5结果:
5 [‘鸡蛋0‘, ‘鸡蛋1‘, ‘鸡蛋2‘, ‘鸡蛋3‘, ‘鸡蛋4‘]

ps4:

生成器表达式(基于迭代器__next__方法进行取值)

 1 laomuji=(‘鸡蛋%s‘ %i for i in range(10)) #生成器表达式
 2 print(laomuji)
 3
 4 print(laomuji.__next__())  #基于迭代器__next__方法进行取值
 5 print(laomuji.__next__())
 6 print(next(laomuji))
 7 print(next(laomuji))
 8 print(next(laomuji))
 9 print(next(laomuji))
10 print(next(laomuji))
11 print(next(laomuji))
12 print(next(laomuji))
13 print(next(laomuji))
14 #print(next(laomuji))   #超出边界,当for循环结束时,捕捉到StopIteration异常,终止迭代

执行结果:

 1 <generator object <genexpr> at 0x010EBAB0>
 2 鸡蛋0
 3 鸡蛋1
 4 鸡蛋2
 5 鸡蛋3
 6 鸡蛋4
 7 鸡蛋5
 8 鸡蛋6
 9 鸡蛋7
10 鸡蛋8
11 鸡蛋9

ps5:

其它

1 l=[1,2,3,34]
2 #map(func,l)   #可迭代对象
3 print(sum(l))  #求和,使用的是__iter__()方法转换成可迭代对象
4
5 #生成100000000
6 print(sum(list(range(100000000))))
7
8 #sum传给生成器生成一个列表
9 print(sum(i for i in range(10000000000000)))   #没有运行结果

执行结果:

1 40
2
3 4999999950000000

总结:

1.把列表解析的[]换成()得到的就是生成器表达式

2.列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节省内存

3.Python不但使用迭代器协议,让for循环变得更加通用。大部分内置函数,也是使用迭代器协议访问对象的。例如, sum函数是Python的内置函数,该函数使用迭代器协议访问对象,而生成器实现了迭代器协议,所以,我们可以直接这样计算一系列值的和。

时间: 2024-10-25 06:12:30

python基础-迭代器和生成器的相关文章

python基础----迭代器、生成器、协程函数

一.什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退) 2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法) 3.协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象. 二,为什么要用迭代器 优点: 1:迭代器提供了一种不依赖于索引的取值方式,

python基础-------迭代器,生成器,协程函数

1,迭代器协议: 1.1 迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退) 1.2. 可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法) 1.3. 协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象 2,迭代器: 1.1:为什么要用迭代器: 1.2 优点:迭代器提

python之迭代器与生成器

python之迭代器与生成器 可迭代 假如现在有一个列表,有一个int类型的12345.我们循环输出. list=[1,2,3,4,5] for i in list: print(i) for i in 12345: print(i) 结果: Traceback (most recent call last): File "C:/Pycham/生成器与迭代器/test1.py", line 6, in <module> for i in 12345: TypeError:

第五篇、Python之迭代器与生成器

1.迭代和递归等概念 循环(loop):指的是在满足条件的情况下,重复执行同一段代码.比如,while语句,for循环. 迭代(iterate):指的是按照某种顺序逐个访问列表中的每一项.比如,for语句.Python中,迭代永远是取出元素本身,而非元素的索引.对于有序集合,元素确实是有索引的.使用 enumerate() 函数获得索引. 递归(recursion):指的是一个函数不断调用自身的行为.比如,以编程方式输出著名的斐波纳契数列. 遍历(traversal):指的是按照一定的规则访问树

Python的迭代器和生成器

先说迭代器,对于string.list.dict.tuple等这类容器对象,使用for循环遍历是很方便的就,在后台for语句对容器对象对象调用iteration()函数,这是python的内置函数,iter()会返回一个定义next()方法的迭代器对象,它在容器中逐个访问容器内元素,next()也是python的内置函数.在没有后续元素是,调用next()会抛出一个StopIteration异常 上面说的都是python自带的容器对象,它们都实现了相应的迭代器方法,自定义类的遍历怎么实现,方法是

python中迭代器和生成器。

前言:很多python教程中,对python的解释不容易理解,本文记录自己的理解和体会,是对迭代器和生成器的初步理解. 迭代器: 迭代器的实质是实现了next()方法的对象,常见的元组.列表.字典都是迭代器. 迭代器中重点关注两种方法: __iter__方法:返回迭代器自身.可以通过python内建函数iter()调用. __next__方法:当next方法被调用的时候,迭代器会返回它的下一个值,如果next方法被调用,但迭代器没有只可以返回,就会引发一个StopIteration异常.该方法可

【Python】迭代器、生成器、yield单线程异步并发实现详解

转自http://blog.itpub.net/29018063/viewspace-2079767 大家在学习python开发时可能经常对迭代器.生成器.yield关键字用法有所疑惑,在这篇文章将从理论+程序调试验证的方式详细讲解这部分知识,话不多说,直接进入主题. 一.迭代器(Iterater):     首先介绍迭代器,迭代器是访问集合元素的一种方式,迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.是不是觉得跟for循环很像?但是迭代器有几个特性需记住:    1.访问者

python之 迭代器,生成器

什么叫跌代: 可以将某个数据集合内的数据一个一个挨着取出来就叫做跌代. 迭代器协议: 可以被跌代要满足的要求叫做可迭代协议,可迭代对象必须提供一个next的方法,执行该方法要么返回跌代中的下一项,要么就引起一个StopIteration异常,以终止跌代(跌代只能往后走,而不能往前退) python中的for循环: for循环的本质就是遵循迭代器协议去访问对象,for循环可以遍历(字符串,列表,元祖,字典,集合,文件对象)这些对象都是不可迭代对象,只不过在for循环时,调用了他们内部的-iter-

day13 python学习 迭代器,生成器

1.可迭代:当我们打印 print(dir([1,2]))   在出现的结果中可以看到包含 '__iter__', 这个方法,#次协议叫做可迭代协议 包含'__iter__'方法的函数就是可迭代函数 字符串.列表.元组.字典.集合都可以被for循环,说明他们都是可迭代的. 2.迭代器 iterator l = [1,2,3,4] l_iter = l.__iter__() #迭代器的生成 item = l_iter.__next__() #迭代器的使用,用此方法一一钓鱼迭代器中的数值 print