首页 > 编程语言 > 详细

Python中的可迭代对象,迭代器与生成器

时间:2019-05-26 14:40:55      阅读:117      评论:0      收藏:0      [点我收藏+]

先来看一张概览图,关于容器(container)、可迭代对象(Iterable)、迭代器(iterator)、生成器(generator)。

技术分享图片

 

一、容器(container)

  容器就是一个用来存储多个元素的数据结构,常见的容器包括【列表】、【元组】、【字典】、【集合】、【字符串】。

  容器有两个特点:1. 容器中的元素可通过迭代获取 2. 所有容器中的元素被存储在内存中。

二、可迭代对象(Iterable)

  可迭代对象,简单的说就是可以被迭代获取的对象,iterable定义了可返回迭代器的__iter__方法。

  通过使用iter()方法,我们能将可迭代对象返回成迭代器。例如列表:

 1 from collections import Iterable
 2 # 定义一个列表,其本身是可迭代对象
 3 list_a = [a, b, c]
 4 isinstance(list_a, Iterable) # True
 5 new_a = iter(list_a)
 6 
 7 # 对迭代器调用next()方法
 8 >>> next(new_a)
 9 a
10 >>> next(new_a)
11 b
12 >>> next(new_a)
13 c
14 >>> next(new_a) # 抛出StopIteration异常

三、迭代器(Iterator)

  迭代器是一个带状态的对象,迭代器内部持有一个状态,该状态用于记录当前迭代所在位置,以便于下次迭代的时候获取正确

  的元素。迭代器可以通过next()方法来迭代获取下一个值。

  迭代器实现了__iter__() 和 __next__()方法。而且,迭代器不会一次性吧所有元素都加载到内存,而是需要的时候才返回结果。 

 1 from collections import Iterable
 2 # 定义一个列表,其本身是可迭代对象
 3 list_a = [a, b, c]
 4 isinstance(list_a, Iterable) # True
 5 new_a = iter(list_a)
 6 
 7 # 对迭代器调用next()方法
 8 >>> next(new_a)
 9 a
10 >>> next(new_a)
11 b
12 >>> next(new_a)
13 c
14 >>> next(new_a) # 抛出StopIteration异常

  迭代器每次调用next()方法的时候做两件事:1. 为下一次调用next()方法修改状态  2. 生成当前调用的返回结果。

  当我们第一次调用next(new_a)之后,当前状态改为即指向a,且输出a,当我们第二次调用的时候,输出b,并且将

  当前状态改为指向b...

四、生成器

  生成器是一种特殊的迭代器。特殊在我们可以通过send()方法像生成器中传入数据,而迭代器只能将数据输出。

  其主要的特点有:

  1、生成器拥有迭代器的迭代传出数据的功能,但用关键字yield来替代迭代器中的__next__()方法来实现,而拥有yield关键字的函数

  就是生成器函数。

  2、生成器可以传入数据进行计算(不同于迭代器),并根据变量内容计算结果后返回。

  3、迭代器不会一次把所有的元素加载到内存,而是调用的时候才生成返回结果(这点相同于迭代器)

  4、可以通过for循环进行迭代(因为生成器是迭代器)

  总结:生成器是一种特殊的迭代器,其具有传入数据的功能。

  下面借助一个简短的程序来具体解释一下yield执行过程: 

 1 def generator_1():
 2     y = 0
 3     r = here
 4     while True:
 5         x = yield r
 6         
 7 g_1 = generator_1()
 8 g_1.send(None)
 9 g_1.send(1)
10 g_1.send(2)

  首先我们写了一个很简单的生成器函数,然后我们定义了一个生成器对象g_1,当我们启动生成器的时候第一个send()只能传入None

  为什么只能是None呢,我们来看其具体执行过程,从函数的第一行开始执行,然后一直到 x = yield r,根据从右向左执行的原则,首先

  执行yield r 然后程序终止,并没有赋值语句,因此,第一个send()只能传入None。当第二次send()时,从上一次中断的地方开始执行,

  上一次是中断在了赋值,那么我们开始从赋值执行,即 x = 1...后边的类似。

 

  参考:https://blog.csdn.net/SL_World/article/details/86507872  作者:SL_World

Python中的可迭代对象,迭代器与生成器

原文:https://www.cnblogs.com/thesong/p/10925804.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!