简介
本节介绍一些与生成器相关的其他主题,包括生成器表达式和 itertools 模块。
This tutorial is from open-source community. Access the source code
💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版
本节介绍一些与生成器相关的其他主题,包括生成器表达式和 itertools 模块。
列表推导式的生成器版本。
>>> a = [1,2,3,4]
>>> b = (2*x for x in a)
>>> b
<generator object at 0x58760>
>>> for i in b:
... print(i, end=' ')
...
2 4 6 8
>>>
与列表推导式的区别:
通用语法:
(<表达式> for i in s if <条件>)
它也可以用作函数参数:
sum(x*x for x in a)
它可以应用于任何可迭代对象:
>>> a = [1,2,3,4]
>>> b = (x*x for x in a)
>>> c = (-x for x in b)
>>> for i in c:
... print(i, end=' ')
...
-1 -4 -9 -16
>>>
生成器表达式的主要用途是在对序列执行某些计算但只使用结果一次的代码中。例如,从文件中去除所有注释:
f = open('somefile.txt')
lines = (line for line in f if not line.startswith('#'))
for line in lines:
...
f.close()
使用生成器,代码运行得更快且占用内存少。它就像应用于流的过滤器。
itertools
模块itertools
是一个库模块,包含各种用于帮助处理迭代器/生成器的函数。
itertools.chain(s1,s2)
itertools.count(n)
itertools.cycle(s)
itertools.dropwhile(predicate, s)
itertools.groupby(s)
itertools.ifilter(predicate, s)
itertools.imap(function, s1,... sN)
itertools.repeat(s, n)
itertools.tee(s, ncopies)
itertools.izip(s1,..., sN)
所有函数都以迭代方式处理数据。它们实现了各种迭代模式。
更多信息请参考 PyCon '08 的教程 Generator Tricks for Systems Programmers 。
在之前的练习中,你编写了一些代码来跟踪写入日志文件的行,并将它们解析成一系列行。本练习在此基础上继续进行。确保 stocksim.py
仍在运行。
生成器表达式是列表推导式的生成器版本。例如:
>>> nums = [1, 2, 3, 4, 5]
>>> squares = (x*x for x in nums)
>>> squares
<generator object <genexpr> at 0x109207e60>
>>> for n in squares:
... print(n)
...
1
4
9
16
25
与列表推导式不同,生成器表达式只能使用一次。因此,如果你再尝试另一个for循环,就不会得到任何结果:
>>> for n in squares:
... print(n)
...
>>>
生成器表达式有时会放在函数参数中。一开始看起来有点奇怪,但试试这个实验:
>>> nums = [1,2,3,4,5]
>>> sum([x*x for x in nums]) ## 一个列表推导式
55
>>> sum(x*x for x in nums) ## 一个生成器表达式
55
>>>
在上面的例子中,如果处理的是一个大列表,使用生成器的第二个版本会显著减少内存使用。
在你的 portfolio.py
文件中,你进行了一些涉及列表推导式的计算。尝试用生成器表达式替换这些。
生成器表达式常常是小型生成器函数的有用替代品。例如,不用编写这样的函数:
def filter_symbols(rows, names):
for row in rows:
if row['name'] in names:
yield row
你可以编写如下代码:
rows = (row for row in rows if row['name'] in names)
修改 ticker.py
程序,酌情使用生成器表达式。
恭喜你!你已经完成了“更多生成器”实验。你可以在LabEx中练习更多实验来提升你的技能。