旗下导航:搜·么
当前位置:网站首页 > Python教程 > 正文

python生成器与迭代器的区分【Python教程】,python,生成器,迭代器

作者:搜教程发布时间:2019-11-27分类:Python教程浏览:44评论:0


导读:关于list、string、tuple、dict等这些容器对象,运用for轮回遍历是很轻易的。在背景for语句对容器对象挪用iter()函数。iter()是python内置函数。...

关于list、string、tuple、dict等这些容器对象,运用for轮回遍历是很轻易的。在背景for语句对容器对象挪用iter()函数。iter()是python内置函数。 iter()函数会返回一个定义了next()要领的迭代器对象,它在容器中逐一接见容器内的元素。next()也是python内置函数。在没有后续元素时,next()会抛出一个StopIteration非常,关照for语句轮回完毕。

迭代器

迭代器是用来协助我们纪录每次迭代接见到的位置,当我们对迭代器运用next()函数的时刻,迭代器会向我们返回它所纪录位置的下一个位置的数据。实际上,在运用next()函数的时刻,挪用的就是迭代器对象的_next_要领(Python3中是对象的_next_要领,Python2中是对象的next()要领)。所以,我们要想组织一个迭代器,就要完成它的_next_要领。但这还不够,python请求迭代器本身也是可迭代的,所以我们还要为迭代器完成_iter_要领,而_iter_要领要返回一个迭代器,迭代器本身恰是一个迭代器,所以迭代器的_iter_要领返回本身self即可。

一些术语的诠释:

1,迭代器协定:对象须要供应next()要领,它要么返回迭代中的下一项,要么就引发一个StopIteration非常,以停止迭代。
2,可迭代对象:完成了迭代器协定对象。list、tuple、dict都是Iterable(可迭代对象),但不是Iterator(迭代器对象)。但能够运用内建函数iter() ,把这些都变成Iterable(可迭代器对象)。
3,for item in Iterable 轮回的实质就是先经由过程iter()函数猎取可迭代对象Iterable的迭代器,然后对猎取到的迭代器不停挪用next()要领来猎取下一个值并将其赋值给item,当碰到StopIteration的非常后轮回完毕。

相干引荐:《Python视频教程》

Python自带容器对象案例:

# 随意定义一个list
listArray=[1,2,3]
# 运用iter()函数
iterName=iter(listArray)
print(iterName)
# 效果以下:是一个列表list的迭代器
# <list_iterator object at 0x0000017B0D984278>
 
print(next(iterName))
print(next(iterName))
print(next(iterName))
print(next(iterName))#没有迭代到下一个元素,直接抛出非常
# 1
# 2
# 3
# Traceback (most recent call last):
# File "Test07.py", line 32, in <module>
# StopIteration

Python中一个完成了_iter_要领和_next_要领的类对象,就是迭代器,以下案例是盘算菲波那切数列的案例

class Fib(object):
 def __init__(self, max):
  super(Fib, self).__init__()
  self.max = max
 
 def __iter__(self):
  self.a = 0
  self.b = 1
  return self
 
 def __next__(self):
  fib = self.a
  if fib > self.max:
   raise StopIteration
  self.a, self.b = self.b, self.a + self.b
  return fib
 
# 定义一个main函数,轮回遍历每一个菲波那切数
def main():
 # 20之内的数
 fib = Fib(20)
 for i in fib:
  print(i)
 
# 测试
if __name__ == '__main__':
 main()

诠释申明:

在本类的完成中,定义了一个_iter_(self)要领,这个要领是在for轮回遍用时被iter()挪用,返回一个迭代器。由于在遍历的时刻,是直接挪用的python内置函数iter() ,由iter()经由过程挪用_iter_(self)取得对象的迭代器。有了迭代器,就能够逐一遍历元素了。而逐一遍历的时刻,也是运用内置的next()函数经由过程挪用对象的_next_(self)要领对迭代器对象举行遍历。所以要完成_iter_(self)和_next_(self)这两个要领。

而且由于完成了_next_(self)要领,所以在完成_iter_(self)的时刻,直接返回self就能够。

总结一句话就是:

在轮回遍历自定义容器对象时,会运用python内置函数iter()挪用遍历对象的_iter_(self)取得一个迭代器,以后再轮回对这个迭代器运用next()挪用迭代器对象的_next_(self) 。

注重点: _iter_(self)只会被挪用一次,而_next_(self)会被挪用 n 次,直到涌现StopIteration非常。

生成器

作用:

耽误操纵。也就是在须要的时刻才发生效果,不是马上发生效果。

注重事项:

生成器是只能遍历一次的。
生成器是一类迥殊的迭代器。

分类:

第一类:生成器函数:照样运用 def 定义函数,然则,运用yield而不是return语句返回效果。yield语句一次返回一个效果,在每一个效果中心,挂起函数的状况,以便下次从它脱离的处所继承实行。

# 菲波那切数列
def Fib(max):
 n, a, b = 0, 0, 1
 while n < max:
  yield b
  a, b = b, a + b
  n = n + 1
 return '亲!没有数据了...'
# 挪用要领,生成出10个数来
f=Fib(10)
# 运用一个轮回捕捉末了return 返回的值,保留在非常StopIteration的value中
while True:
 try:
  x=next(f)
  print("f:",x)
 except StopIteration as e:
  print("生成器末了的返回值是:",e.value)
  break

第二类:生成器表达式:类似于列表推导,只不过是把一对大括号[]变换为一对小括号()。然则,生成器表达式是按需发生一个生成器效果对象,要想拿到每一个元素,就须要轮回遍历。

以下案例加以申明:

# 一个列表
xiaoke=[2,3,4,5]
# 生成器generator,类似于list,然则是把[]改成()
gen=(a for a in xiaoke)
for i in gen:
 print(i)
#效果是:
2
3
4
5
# 为何要运用生成器?由于效力。
# 运用生成器表达式庖代列表推导式能够同时节约 cpu 和 内存(RAM)。
# 假如你组织一个列表(list)的目标仅仅是传递给别的函数,
# 比方 传递给tuple()或许set(), 那就用生成器表达式替换吧! 
#本案例是直接把列表转化为元组
kk=tuple(a for a in xiaoke)
print(kk)
#效果是:
(2, 3, 4, 5) 
# python内置的一些函数,能够辨认这是生成器表达式,表面有一对小括号,就是生成器
result1=sum(a for a in range(3))
print(result1)
# 列表推导式
result2=sum([a for a in range(3)])
print(result2)

区分:

生成器能做到迭代器能做的所有事,而且由于自动创建了 iter()和 next()要领,生成器显得迥殊简约,而且生成器也是高效的,运用生成器表达式庖代列表剖析能够同时节约内存。除了创建和保留顺序状况的自动要领,当发生器闭幕时,还会自动抛出 StopIteration 非常。

以上就是python生成器与迭代器的区分的细致内容,更多请关注ki4网别的相干文章!

标签:python生成器迭代器


欢迎 发表评论: