python(迭代器和生成器)

迭代器

:(列表,元组,字典,集合,字符串,文件)
迭代:每次重复的过程成为迭代的过程,每次迭代得到的结果,回作为下次迭代的初始值
迭代器:可以被next()函数调用并不断返回下一个值的对象称为迭代器
它只是实现了__next__()方法的对象,并不是容器
Iter()(iteration)
Next()
迭代器魔法方法:
iter() 返回对象本身:self
next()
补充:
1如何判断一个容器是否有迭代功能?
查看该容器是否具有__next
_()和__iter__()方法
2 for语句如何判断迭器里面已经取空了?
迭代器每次通过__next__()方法返回一个元素,并指向下一个元素,如果当前位置已无元素,通过抛出StopIteration异常表示
3 python原生数据结构中,只有集合只能用迭代器进行访问 。
生成器(生成器是一个特殊的迭代器)
生成器的出现使python模仿协同程序的概念能够实现
协同程序:可以运行的独立函数调用,函数可以暂停或者挂起,并在需要的时候从程序离开的地方继续或者重新开始
注解:
1.如果函数中出现yield时,则这个函数被定义成生成器
2.yield 相当与函数中的return语句,不同的时候,yield是被暂停,程序能继续进行执行
注意:
1生成器都是Iterator对象,但list、dict、str虽然是Iterable(可迭代对象),却不是Iterator(迭代器)。
2以直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,如list,tuple,dict,set,str等
一类是generator,包括生成器和带yield的generator function
统称为可迭代对象:Iterable
3为什么list、dict、str等数据类型不是Iterator?
这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

4判断一个对象是否是可迭代,迭代器
from collections import Iterator #迭代器
from collections import Iterable #可迭代对象

print(isinstance(s,Iterator)) #判断是不是迭代器
print(isinstance(s,Iterable)) #判断是不是可迭代对象
5可迭代对象通过iter转成迭代器对象
6
小结:
• 凡是可作用于for循环的对象都是Iterable类型;
• 凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
• 集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
7 send()和next()的区别就在于send可传递参数给yield表达式,这时候传递的参数就会作为yield表达式的值,而yield的参数是返回给调用者的值,也就是说send可以强行修改上一个yield表达式值。
8 send()和next()都有返回值,他们的返回值是当前迭代遇到的yield的时候,yield后面表达式的值,其实就是当前迭代yield后面的参数。
9 第一次调用时候必须先next()后send(),否则会报错,send后之所以为None是因为这时候没有上一个yield,所以也可以认为next()等同于send(None),(send是给上一个yield复制对象进行复制)
10不管是send还是next都是跑到下一个yield进行操作,并把yield之后的值返回来
Eg
1.
def A():
x = yield “这是第一次yield”
print(“第一个yield和第二个yield之间,第一个x是:{}”.format(x))
x = yield “这是第二次yield”
print(“第二个yield和第三个yield之间,第二个x是:{}”.format(x))
x = yield “这是第三次yield”

a = A()
print(a)
print(type(a))
print(a.next())
print(a.next())
print(a.send(“第一次使用send”))
实行结果:
这是第一次yield
第一个yield和第二个yield之间,第一个x是:None
这是第二次yield
第二个yield和第三个yield之间,第二个x是:第一次使用send
这是第三次yield
2.

利用yield求出指定数字开始,指定个数的素数

def is_p(number):
while True:
if number == 1:
number += 1
continue
elif number == 2:
yield number
number += 1
else:
number > 1
for i in range(2, number):
if not number % i:
number += 1
break
else:
yield number
number += 1
#第一个参数是指定开始数字,第二个参数是打印多少个参数
def get_p(number, count):
t = is_p(number)
for i in range(count):
print(t.next())

get_p(2, 10)
实行结果:
2
3
5
7
11
13
17
19
23
29

迭代器

:(列表,元组,字典,集合,字符串,文件)
迭代:每次重复的过程成为迭代的过程,每次迭代得到的结果,回作为下次迭代的初始值
迭代器:可以被next()函数调用并不断返回下一个值的对象称为迭代器
它只是实现了__next__()方法的对象,并不是容器
Iter()(iteration)
Next()
迭代器魔法方法:
iter() 返回对象本身:self
next()
补充:
1如何判断一个容器是否有迭代功能?
查看该容器是否具有__next
_()和__iter__()方法
2 for语句如何判断迭器里面已经取空了?
迭代器每次通过__next__()方法返回一个元素,并指向下一个元素,如果当前位置已无元素,通过抛出StopIteration异常表示
3 python原生数据结构中,只有集合只能用迭代器进行访问 。
生成器(生成器是一个特殊的迭代器)
生成器的出现使python模仿协同程序的概念能够实现
协同程序:可以运行的独立函数调用,函数可以暂停或者挂起,并在需要的时候从程序离开的地方继续或者重新开始
注解:
1.如果函数中出现yield时,则这个函数被定义成生成器
2.yield 相当与函数中的return语句,不同的时候,yield是被暂停,程序能继续进行执行
注意:
1生成器都是Iterator对象,但list、dict、str虽然是Iterable(可迭代对象),却不是Iterator(迭代器)。
2以直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,如list,tuple,dict,set,str等
一类是generator,包括生成器和带yield的generator function
统称为可迭代对象:Iterable
3为什么list、dict、str等数据类型不是Iterator?
这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

4判断一个对象是否是可迭代,迭代器
from collections import Iterator #迭代器
from collections import Iterable #可迭代对象

print(isinstance(s,Iterator)) #判断是不是迭代器
print(isinstance(s,Iterable)) #判断是不是可迭代对象
5可迭代对象通过iter转成迭代器对象
6
小结:
• 凡是可作用于for循环的对象都是Iterable类型;
• 凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
• 集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
7 send()和next()的区别就在于send可传递参数给yield表达式,这时候传递的参数就会作为yield表达式的值,而yield的参数是返回给调用者的值,也就是说send可以强行修改上一个yield表达式值。
8 send()和next()都有返回值,他们的返回值是当前迭代遇到的yield的时候,yield后面表达式的值,其实就是当前迭代yield后面的参数。
9 第一次调用时候必须先next()后send(),否则会报错,send后之所以为None是因为这时候没有上一个yield,所以也可以认为next()等同于send(None),(send是给上一个yield复制对象进行复制)
10不管是send还是next都是跑到下一个yield进行操作,并把yield之后的值返回来
Eg
1.
def A():
x = yield “这是第一次yield”
print(“第一个yield和第二个yield之间,第一个x是:{}”.format(x))
x = yield “这是第二次yield”
print(“第二个yield和第三个yield之间,第二个x是:{}”.format(x))
x = yield “这是第三次yield”

a = A()
print(a)
print(type(a))
print(a.next())
print(a.next())
print(a.send(“第一次使用send”))
实行结果:
这是第一次yield
第一个yield和第二个yield之间,第一个x是:None
这是第二次yield
第二个yield和第三个yield之间,第二个x是:第一次使用send
这是第三次yield
2.

利用yield求出指定数字开始,指定个数的素数

def is_p(number):
while True:
if number == 1:
number += 1
continue
elif number == 2:
yield number
number += 1
else:
number > 1
for i in range(2, number):
if not number % i:
number += 1
break
else:
yield number
number += 1
#第一个参数是指定开始数字,第二个参数是打印多少个参数
def get_p(number, count):
t = is_p(number)
for i in range(count):
print(t.next())

get_p(2, 10)
实行结果:
2
3
5
7
11
13
17
19
23
29

猜你喜欢

转载自blog.csdn.net/weixin_42970234/article/details/84350969