python中生成器(关键字yield)

python中生成器(关键字yield)

  • 简介
    • 可迭代对象(Iterable)
    • 迭代器(Iterator)
    • 迭代器(Iterator)
    • ⽣成器(Generators)
  • 用法
          • 第一种用法
          • 第二种用法:使用python内置函数next()
    • 理解可迭代对象和迭代器
            • 首先我们看一个例子(遍历字符串)

简介

⾸先我们要理解迭代器(iterators)。 迭代器是可以遍历⼀个容器(特别是列表) 的对象。 然⽽, ⼀个迭代器在遍历并读取⼀个容器的数据元素时, 并不会执⾏⼀个迭代。 你可能有点晕了, 那我们来个慢动作。 换句话说这⾥有三个部分:

  1. 可迭代对象(Iterable)
  2. 迭代器(Iterator)
  3. 迭代(Iteration)

上⾯这些部分互相联系。 我们会先各个击破来讨论他们, 然后再讨论⽣成器(generators)。

可迭代对象(Iterable)

Python中任意的对象, 只要它定义了可以返回⼀个迭代器的__iter__⽅法, 或者定义了可以⽀持下标索引的__getitem__⽅法(这些双下划线⽅法会在其他章节中全⾯解释),那么它就是⼀个可迭代对象。 简单说, 可迭代对象就是能提供迭代器的任意对象。

迭代器(Iterator)

任意对象, 只要定义了next(Python2) 或者__next__⽅法, 它就是⼀个迭代器。 就这么简单。

迭代器(Iterator)

⽤简单的话讲, 它就是从某个地⽅(⽐如⼀个列表) 取出⼀个元素的过程。 当我们使⽤⼀个循环来遍历某个东西时, 这个过程本⾝就叫迭代。

⽣成器(Generators)

⽣成器也是⼀种迭代器, 但是你只能对其迭代⼀次。 这是因为它们并没有把所有的值存在内存中, ⽽是在运⾏时⽣成值。 你通过遍历来使⽤它们, 要么⽤⼀个“for”循环, 要么将它们传递给任意可以进⾏迭代的函数和结构。 ⼤多数时候⽣成器是以函数来实现的。 然⽽,它们并不返回⼀个值, ⽽是yield(暂且译作“⽣出”)⼀个值。

用法

第一种用法
#!coding:utf8

def num_generators():
    for i in range(0,3):
        yield i

if __name__=='__main__':
   for num in num_generators():
       print num

输出结果是
0
1
2

第二种用法:使用python内置函数next()
#!coding:utf8

def num_generators():
    for i in range(0,3):
        yield i

if __name__=='__main__':
    nums = num_generators()
    print next(nums), next(nums), next(nums)
    print next(nums)

结果如下:
0 1 2
File “E:/pycharmworkspace/deep/csdn/csdn.py”, line 10, in
print next(nums)
StopIteration
我们可以看到, 在yield掉所有的值后, next()触发了⼀个StopIteration的异常。这个异常告诉我们所有的值都已经被yield完了。联想一下为什么使用for循环就没有就没这异常呢,原因很简单:for循环会自动捕捉到这个异常并停⽌调⽤next()

理解可迭代对象和迭代器

首先我们看一个例子(遍历字符串)
#!coding:utf8

if __name__=='__main__':
    csdn="CSDN"
    print next(csdn)

运行结果如下
Traceback (most recent call last):
File “E:/pycharmworkspace/deep/csdn/csdn.py”, line 6, in
print next(csdn)
TypeError: str object is not an iterator

由上面的结果可以知道字符串(str)不是一个迭代器,但是我们却是可以用for循环遍历字符串,说明字符串是一个可迭代对象
那么我们如何将一个可迭代对象变成一个迭代器呢?这里我需要引入一个python内置函数iter(),代码如下:

#!coding:utf8

if __name__=='__main__':
    csdn=iter("CSDN")
    print next(csdn),next(csdn),next(csdn),next(csdn)

运行结果如下:
C S D N

你可能感兴趣的:(python,python,生成器,yield)