Python面试题之生成器/迭代器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python面试题之生成器/迭代器相关的知识,希望对你有一定的参考价值。

1.为什么要有生成器?

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。所以,如果列表元素可以按照某种算法推算出来,那我们是否可以。。。

在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator,其实就是一个tuple。

L = [x * x for x in range(10)]
print(L)
print(type(L))

L2 = (x * x for x in range(10))
print(L2)
print(type(L2))

# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# <class ‘list‘>
# <generator object <genexpr> at 0x00FE4FC0>
# <class ‘generator‘>

创建L和L2的区别仅在于最外层的[]()L是一个list,而L2是一个generator。

我们可以直接打印出list的每一个元素,但我们怎么打印出generator的每一个元素呢?

如果要一个一个打印出来,可以通过next()函数获得generator的下一个返回值:

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        print(b)
        a, b = b, a + b
        n = n + 1
    return done

也就是说,上面的函数和generator仅一步之遥。要把fib函数变成generator,只需要把print(b)改为yield b就可以了,这就是定义generator的另一种方法。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:

 

generator是非常强大的工具,在Python中,可以简单地把列表生成式改成generator,也可以通过函数实现复杂逻辑的generator。

要理解generator的工作原理,它是在for循环的过程中不断计算出下一个元素,并在适当的条件结束for循环。对于函数改成的generator来说,遇到return语句或者执行到函数体最后一行语句,就是结束generator的指令,for循环随之结束。

请注意区分普通函数和generator函数,普通函数调用直接返回结果:

>>> r = abs(6)
>>> r
6
generator函数的“调用”实际返回一个generator对象:

>>> g = fib(6)
>>> g
<generator object fib at 0x1022ef948>






以上是关于Python面试题之生成器/迭代器的主要内容,如果未能解决你的问题,请参考以下文章

前端面试题之手写promise

迭代器可迭代对象迭代器对象生成器生成器表达式和相关的面试题

what's the python之可迭代对象迭代器与生成器(附面试题)

python面试题之请谈谈.pyc文件和.py文件的不同之处

Python学习之旅—Day07(生成器与迭代器)

面试题之python基础