Python中的yield

yield是弄啥玩意的?

在介绍yield之前,先有必要看看列表生成式。


在Python中生成一个1-5的列表,可以用range(1,6)或者 xrange(1,6)。

In[5]: for i in xrange(1,6):

...     print i

...

1

2

3

4

5

In[6]: range(1,6)

Out[6]: [1, 2, 3, 4, 5]

那么问题来了,如果要生成1*2,2*2,3*2....n*2这样的列表 该如何做呢?可以先用for循环试试。

In[7]: l_test = []

In[8]: for i in range(1,6):

...     l_test.append(i*2)

...

In[9]: l_test

Out[9]: [2, 4, 6, 8, 10]

这样写虽然达到了我们的目的,但是这样的循环很繁琐,又要声明列表,又要append,而列表生成式可以一句代码搞定。

In[11]: [i*2 for i in range(1,6)]

Out[11]: [2, 4, 6, 8, 10]

是不是so easy?,这就是最简单的一种列表生成式。

虽然列表生成式 相对于 循环来说已经很大程度上解放生产力了,但是当列表元素上百万的时候,我们PC的内存是hold不住的,况且大多数情况可能我们创建了一个上百万个元素的列表 ,而我们真正需要的只要前面几个,这是一种极大地内存浪费。生成器(generator)就是解决这种问题的。

上面我们创建迭代器的时候 是用的[] ,而生成器虽然也是迭代器的一种,但是却用()符号。

In[12]: list1 = [x*2 for x in range(1,6)]

In[13]: list1

Out[13]: [2, 4, 6, 8, 10]

In[14]: generator = (x*2 for x in range(1,6))

In[15]: generator

Out[15]: at 0x0000000003A265E8>

在执行后 list1返回的是列表,而generator返回的是一个生成器,那么如何访问生成器中的元素呢?这里使用.next()方法

In[16]: generator.next()

Out[16]: 2

In[17]: generator.next()

Out[17]: 4

In[18]: generator.next()

Out[18]: 6

In[19]: generator.next()

Out[19]: 8

In[20]: generator.next()

Out[20]: 10

In[21]:

In[21]: generator.next()

Traceback (most recent call last):

File "D:\Anaconda2\lib\site-packages\IPython\core\interactiveshell.py", line 3066, in run_code

exec(code_obj, self.user_global_ns, self.user_ns)

File "", line 1, in

generator.next()

StopIteration

当 生成器中的元素被访问完毕后,会抛出StopIteration异常。

也就是说,generator保存的是一种计算方法,可以使用next()来访问其中的元素。

讲了这么多,到底和yield关键字有什么半毛线关系呢?别急,来看一个例子,如果我想输出 ’I‘,’love‘,’Python‘这三个string,我想每次只输出一个string,而不是一次性都输出,怎么做呢?

In[23]: def printStr():

...     print u'第一个字符'

...     yield "i"

...     print u'第二个字符'

...     yield "love"

...     print u'第三个字符'

...     yield "Python"

...

In[24]: p = printStr()

In[25]: p.next()

第一个字符

Out[25]: 'i'

In[26]: p.next()

第二个字符

Out[26]: 'love'

In[27]: p.next()

第三个字符

Out[27]: 'Python'

很明显 printStr不是一般意义上的函数,而是一个生成器,在执行的过程中,执行到yield时就会暂停,再次执行就会从前一次执行停止的地方开始。

生成器也是会结束的,从上面的例子看到,当执行到最后一行语句时就是generator结束的标志。



微信:

Python中的yield_第1张图片

你可能感兴趣的:(Python中的yield)