Python技术迷

面试题:迭代器和生成器

干咱们这行的,免不了和“迭代器”“生成器”这些词打交道,尤其 Python 里,这俩可是面试高频。

今天咱就从一个经典面试题聊开,说说这俩到底是啥,顺便还帮大家总结一下,遇到相关问题怎么优雅应对,不翻车。

列表推导式 vs 生成器表达式

先抛个问题——有同学在面试被问懵了:

问:将 [] 换成 (),数据结构变了吗?

咱看看这个例子:

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

这不就是个普通列表嘛,输出 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81],再正常不过。

但是你把方括号换成圆括号:

g = (x*x for x in range(10))
print(g)

这输出可不是列表了,而是:

<generator object <genexpr> at 0x...>

看到 generator 这词没?这玩意儿就叫生成器表达式,确实数据结构变了。列表推导式直接给你一整个列表,生成器表达式只给你一个生成器对象,它不会一次性算完所有的值,而是要啥算啥,按需生成。

面试回答思路:
“是的,数据结构变了。用 [] 是列表推导式,生成一个完整的列表,占用实际内存;用 () 是生成器表达式,返回一个生成器对象,按需计算,节省内存。”

为啥有生成器?为啥不用列表?

你想象一下,老板让你处理一份包含一百万条数据的文件,用列表推导式直接全加载,内存炸不炸咱不知道,反正电脑风扇得起飞。

生成器就不一样了,边循环边计算,你要一个,我给一个,别催。这就叫“惰性计算”,省内存不说,还特别适合处理大数据流,比如读取日志文件、爬虫抓取数据等等。

来个小对比:

# 列表:一口气全算出来
L = [x*x for x in range(1000000)]

# 生成器:需要的时候才算
g = (x*x for x in range(1000000))

这俩的内存占用,那叫一个天壤之别,生成器轻飘飘,列表沉甸甸。

生成器的真面目:yield 出场

说到生成器,不提 yield 说不过去。这可是 Python 里一等一的神器。

平时写函数,咱都用 return,一次性扔回去一个值,函数结束。而 yield 就不一样了,它让函数变成一个生成器,每次暂停在 yield,下次从这儿接着来,状态还能保留。

看例子:

defmy_gen():
for i in range(3):
yield i

g = my_gen()
print(next(g))  # 0
print(next(g))  # 1
print(next(g))  # 2

每次 next(g),生成器往前走一步,到了 yield 交个值,暂停。再 next,从上次停的地方接着走,直到抛出 StopIteration,这才算走完。

这种按需产出、状态保存的操作,别说写爬虫,处理大数据、流式传输、协程啥的,简直就是救命稻草。

迭代器和生成器的区别到底在哪儿?

面试官一问,你别慌,咱得分得清:

  • 迭代器(Iterator):只要实现了 __iter__() 和 __next__() 这俩方法的对象,都叫迭代器。它知道自己到哪了,每次 next() 都能拿到下一个元素,取完就抛 StopIteration。

  • 生成器(Generator):生成器本质就是一种特殊的迭代器,自动帮你写好了 __iter__() 和 __next__(),你只需要用 yield 定义它。

换句话说,生成器是迭代器的一种,但写法简单多了,不用自己手动搞那些魔法方法。

再来个例子感受下迭代器的“原生”写法:

classMyIterator:
def__init__(self):
        self.n = 0

def__iter__(self):
return self

def__next__(self):
if self.n < 3:
            val = self.n
            self.n += 1
return val
else:
raise StopIteration

it = MyIterator()
print(next(it))  # 0
print(next(it))  # 1
print(next(it))  # 2

和刚才 yield 写法比,是不是麻烦多了?但效果其实差不多。这也说明了,生成器就是懒人版的迭代器,Python 贴心给我们省事儿。

面试题的最佳回答

问题:将 [] 换成 (),数据结构变了吗?

最佳回答:

“变了,方括号生成的是列表,直接把所有元素存在内存里;圆括号生成的是生成器对象,按需生成元素,只有在迭代时才计算,节省内存。这种生成器表达式特别适合处理大数据或者数据流,避免一次性加载所有数据。”

最后,我为大家打造了一份deepseek的入门到精通教程,完全免费:https://www.songshuhezi.com/deepseek

也可以看我写的这篇文章《DeepSeek满血复活,直接起飞!》来进行本地搭建。

对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。
🔥虎哥私藏精品 热门推荐🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》。

资料包含了《IDEA视频教程》、《最全python面试题库》、《最全项目实战源码及视频》及《毕业设计系统源码》,总量高达650GB,全部免费领取