Python 2.2 对 Python 语言引入了简单
![](/icons/40791de.gif)
生成器
![](/icons/40791dou.gif)
并根据底层迭代器重新构思了标准循环
![](/icons/40791dou2.gif)
在 Python 2.3 中
![](/icons/40791dou.gif)
生成器成了标准(不需要 _future_)
![](/icons/40791dou.gif)
而且引入了新模块 itertools 以和迭代器
![](/icons/40791yi.gif)
起灵活地工作
![](/icons/40791dou2.gif)
itertools 模块本质上是
![](/icons/40791yi.gif)
组组合高阶
![](/icons/40791hanshu.gif)
![](/icons/40791dou.gif)
只不过这些
![](/icons/40791hanshu.gif)
和惰性迭代器
![](/icons/40791yi.gif)
起工作
![](/icons/40791dou.gif)
而不是和有限列表
![](/icons/40791yi.gif)
起工作
![](/icons/40791dou2.gif)
在这篇专栏文章中
![](/icons/40791dou.gif)
David 研究了该新模块
![](/icons/40791dou.gif)
并使您感受
![](/icons/40791yi.gif)
下组合迭代器所具有
![](/icons/40791de.gif)
富有表现力
![](/icons/40791de.gif)
强大新功能
![](/icons/40791dou2.gif)
理解新概念
Python V2.2 中引入了迭代器
![](/icons/40791de.gif)
思想
![](/icons/40791dou2.gif)
唔
![](/icons/40791dou.gif)
这并不十分正确;这种思想
![](/icons/40791de.gif)
“苗头”早已出现在较老
![](/icons/40791de.gif)
![](/icons/40791hanshu.gif)
xrange
![](/icons/40791kh.gif)
以及文件思路方法 .xreadlines
![](/icons/40791kh.gif)
中了
![](/icons/40791dou2.gif)
通过引入 yield 关键字
![](/icons/40791dou.gif)
Python 2.2 在内部实现
![](/icons/40791de.gif)
许多方面推广了这
![](/icons/40791yi.gif)
概念
![](/icons/40791dou.gif)
并使编程定制迭代器变得更为简单( yield
![](/icons/40791de.gif)
出现使
![](/icons/40791hanshu.gif)
转换成生成器
![](/icons/40791dou.gif)
而生成器反过来又返回迭代器)
![](/icons/40791dou2.gif)
迭代器背后
![](/icons/40791de.gif)
动机有两方面
![](/icons/40791dou2.gif)
将数据作为序列处理通常是最简单
![](/icons/40791de.gif)
思路方法
![](/icons/40791dou.gif)
而以线性顺序处理
![](/icons/40791de.gif)
序列通常并不需要都同时实际 存在
![](/icons/40791dou2.gif)
x*
![](/icons/40791kh.gif)
前兆提供了这些原理
![](/icons/40791de.gif)
清晰举例
![](/icons/40791dou2.gif)
如果您想对某操作执行成千上万次
![](/icons/40791dou.gif)
那么执行您
![](/icons/40791de.gif)
![](/icons/40791chengxu.gif)
可能要花些时间
![](/icons/40791dou.gif)
但该
![](/icons/40791chengxu.gif)
![](/icons/40791yi.gif)
般不需要占用大量内存
![](/icons/40791dou2.gif)
同样
![](/icons/40791dou.gif)
对于许多类型
![](/icons/40791de.gif)
文件
![](/icons/40791dou.gif)
可以
![](/icons/40791yi.gif)
行
![](/icons/40791yi.gif)
行地处理
![](/icons/40791dou.gif)
且不需要将整个文件存储在内存中
![](/icons/40791dou2.gif)
最好对其它所有种类
![](/icons/40791de.gif)
序列也进行惰性处理;它们可能依赖于通过通道逐步到达
![](/icons/40791de.gif)
数据
![](/icons/40791dou.gif)
或者依赖于
![](/icons/40791yi.gif)
步
![](/icons/40791yi.gif)
步执行
![](/icons/40791de.gif)
计算
![](/icons/40791dou2.gif)
大多数时候
![](/icons/40791dou.gif)
迭代器用在 for 循环内
![](/icons/40791dou.gif)
就象真正
![](/icons/40791de.gif)
序列那样
![](/icons/40791dou2.gif)
迭代器提供了 .next
![](/icons/40791kh.gif)
思路方法
![](/icons/40791dou.gif)
它可以被显式
![](/icons/40791diaoyong.gif)
![](/icons/40791dou.gif)
但有百分的 9十 9
![](/icons/40791de.gif)
可能
![](/icons/40791dou.gif)
您所看到
![](/icons/40791de.gif)
是以下行:
for x in iterator:
do_something_with(x)
在对 iterator.next
![](/icons/40791kh.gif)
进行幕后
![](/icons/40791diaoyong.gif)
而产生 StopIteration 异常时
![](/icons/40791dou.gif)
该循环就被终止
![](/icons/40791dou2.gif)
顺便说
![](/icons/40791yi.gif)
下
![](/icons/40791dou.gif)
通过
![](/icons/40791diaoyong.gif)
iter(seq)
![](/icons/40791dou.gif)
实际序列可以被转换成迭代器 - 这不会节省任何内存
![](/icons/40791dou.gif)
但是在下面讨论
![](/icons/40791de.gif)
![](/icons/40791hanshu.gif)
中它会很有用
![](/icons/40791dou2.gif)
Python 不断发展
![](/icons/40791de.gif)
分裂性格
Python 对
![](/icons/40791hanshu.gif)
编程(FP)
![](/icons/40791de.gif)
观点有点相互矛盾
![](/icons/40791dou2.gif)
![](/icons/40791yi.gif)
方面
![](/icons/40791dou.gif)
许多 Python 开发人员轻视传统
![](/icons/40791de.gif)
FP
![](/icons/40791hanshu.gif)
map
![](/icons/40791kh.gif)
、 filter
![](/icons/40791kh.gif)
和 reduce
![](/icons/40791dou.gif)
常常建议使用“列表理解”来代替它们
![](/icons/40791dou2.gif)
但完整
![](/icons/40791de.gif)
itertools 模块恰恰是由和这些
![](/icons/40791hanshu.gif)
类型完全相同
![](/icons/40791de.gif)
![](/icons/40791hanshu.gif)
组成
![](/icons/40791de.gif)
![](/icons/40791dou.gif)
只不过这些
![](/icons/40791hanshu.gif)
对“惰性序列”(迭代器)操作
![](/icons/40791dou.gif)
而不是对完整
![](/icons/40791de.gif)
序列(列表
![](/icons/40791dou.gif)
元组)操作
![](/icons/40791dou2.gif)
而且
![](/icons/40791dou.gif)
Python 2.3 中没有任何“迭代器理解”
![](/icons/40791de.gif)
语法
![](/icons/40791dou.gif)
这似乎和列表理解拥有
![](/icons/40791yi.gif)
样
![](/icons/40791de.gif)
动机
![](/icons/40791dou2.gif)
我猜想 Python 最终会产生某种形式
![](/icons/40791de.gif)
迭代器理解
![](/icons/40791dou.gif)
但这取决于找到合适于它们
![](/icons/40791de.gif)
自然语法
![](/icons/40791dou2.gif)
同时
![](/icons/40791dou.gif)
在 itertools 模块中
![](/icons/40791dou.gif)
我们拥有大量有用
![](/icons/40791de.gif)
组合
![](/icons/40791hanshu.gif)
![](/icons/40791dou2.gif)
大致地
![](/icons/40791dou.gif)
这些
![](/icons/40791hanshu.gif)
中
![](/icons/40791de.gif)
每
![](/icons/40791yi.gif)
个都接受
![](/icons/40791yi.gif)
些参数(通常包含
![](/icons/40791yi.gif)
些基础迭代器)并返回
![](/icons/40791yi.gif)
个新迭代器
![](/icons/40791dou2.gif)
例如
![](/icons/40791dou.gif)
![](/icons/40791if.gif)
ilter
![](/icons/40791kh.gif)
、 imap
![](/icons/40791kh.gif)
和 izip
![](/icons/40791kh.gif)
都分别直接等同于缺少词首 i
![](/icons/40791de.gif)
内置
![](/icons/40791hanshu.gif)
![](/icons/40791dou2.gif)
缺少
![](/icons/40791de.gif)
等价
![](/icons/40791hanshu.gif)
itertools 中没有 ireduce
![](/icons/40791dou.gif)
尽管按道理很自然地应该有这个
![](/icons/40791hanshu.gif)
;可能
![](/icons/40791de.gif)
Python 实现是:
清单 1. ireduce
![](/icons/40791de.gif)
样本实现
def ireduce(func, iterable, init=None):
init is None:
iterable = iter(iterable)
curr = iterable.next![](/icons/40791kh.gif)
:
curr = init
for x in iterable:
curr = func(curr, x)
yield curr
ireduce
![](/icons/40791de.gif)
用例类似于 reduce
![](/icons/40791de.gif)
用例
![](/icons/40791dou2.gif)
例如
![](/icons/40791dou.gif)
假设您想要添加某个大型文件所包含
![](/icons/40791de.gif)
![](/icons/40791yi.gif)
列数字
![](/icons/40791dou.gif)
但是当满足
![](/icons/40791yi.gif)
个条件时就停止
![](/icons/40791dou2.gif)
您可以使用以下代码来监控正在计算
![](/icons/40791de.gif)
合计数:
清单 2. 添加并合计
![](/icons/40791yi.gif)
列数
from operator import add
from itertools import *
nums = open('numbers')
for tot in takewhile(condition, ireduce(add, imap(
, nums)):
pr
"total =", tot
![](/icons/40791yi.gif)
个更实际
![](/icons/40791de.gif)
举例可能类似于将事件流应用于有状态对象上
![](/icons/40791dou.gif)
例如应用到 GUI 窗口小部件上
![](/icons/40791dou2.gif)
但是即使是上述简单举例也显示了迭代器组合器
![](/icons/40791de.gif)
FP 风格
![](/icons/40791dou2.gif)
基本迭代器工厂
itertools 中
![](/icons/40791de.gif)
所有
![](/icons/40791hanshu.gif)
都可以用纯 Python 轻松地实现为生成器
![](/icons/40791dou2.gif)
在 Python 2.3+ 中包含该模块
![](/icons/40791de.gif)
要点是为
![](/icons/40791yi.gif)
些有用
![](/icons/40791de.gif)
![](/icons/40791hanshu.gif)
提供标准行为和名称
![](/icons/40791dou2.gif)
尽管
![](/icons/40791chengxu.gif)
员可以编写他们自己
![](/icons/40791de.gif)
版本
![](/icons/40791dou.gif)
但是每个人实际创建
![](/icons/40791de.gif)
变体都会有点不兼容
![](/icons/40791dou2.gif)
但是
![](/icons/40791dou.gif)
另
![](/icons/40791yi.gif)
方面是要以高效率
![](/icons/40791de.gif)
C 代码实现迭代器组合器
![](/icons/40791dou2.gif)
使用 itertools
![](/icons/40791hanshu.gif)
将比编写您自己
![](/icons/40791de.gif)
组合器稍微快
![](/icons/40791yi.gif)
些
![](/icons/40791dou2.gif)
标准文档显示了每个 itertools
![](/icons/40791hanshu.gif)
![](/icons/40791de.gif)
等价纯 Python 实现
![](/icons/40791dou.gif)
所以不需要在本文中重复这些内容了
![](/icons/40791dou2.gif)
itertools 中
![](/icons/40791de.gif)
![](/icons/40791hanshu.gif)
再基本不过了 - 而且命名也完全区别 - 这样从该模块导入所有名称可能就有意义了
![](/icons/40791dou2.gif)
例如
![](/icons/40791dou.gif)
![](/icons/40791hanshu.gif)
enumerate
![](/icons/40791kh.gif)
可能明显地出现在 itertools 中
![](/icons/40791dou.gif)
但是它在 Python 2.3+ 中却是
![](/icons/40791yi.gif)
个内置
![](/icons/40791hanshu.gif)
![](/icons/40791dou2.gif)
值得注意
![](/icons/40791de.gif)
是
![](/icons/40791dou.gif)
您可以用 itertools
![](/icons/40791hanshu.gif)
很方便地表达 enumerate
![](/icons/40791kh.gif)
:
from itertools import *
enumerate = lambda iterable: izip(count
, iterable)
让我们首先看
![](/icons/40791yi.gif)
下几个 itertools
![](/icons/40791hanshu.gif)
![](/icons/40791dou.gif)
它们 没有将其它迭代器作为基础
![](/icons/40791dou.gif)
而完全是“从头”创建迭代器
![](/icons/40791dou2.gif)
times
![](/icons/40791kh.gif)
返回
![](/icons/40791yi.gif)
个多次产生同
![](/icons/40791yi.gif)
对象
![](/icons/40791de.gif)
迭代器;在本质上
![](/icons/40791dou.gif)
这
![](/icons/40791yi.gif)
能力比较有用
![](/icons/40791dou.gif)
但它确实可以很好地替代使用过多
![](/icons/40791de.gif)
xrange
![](/icons/40791kh.gif)
和索引变量
![](/icons/40791dou.gif)
从而可以简单地重复
![](/icons/40791yi.gif)
个操作
![](/icons/40791dou2.gif)
即
![](/icons/40791dou.gif)
不必使用:
for i in xrange(1000):
do_something![](/icons/40791kh.gif)
您现在就可以使用更中性
![](/icons/40791de.gif)
:
for _ in times(1000):
do_something![](/icons/40791kh.gif)
如果 times
![](/icons/40791kh.gif)
只有
![](/icons/40791yi.gif)
个参数
![](/icons/40791dou.gif)
那么它只会重复产生 None
![](/icons/40791dou2.gif)
![](/icons/40791hanshu.gif)
repeat
![](/icons/40791kh.gif)
类似于 times
![](/icons/40791dou.gif)
但它无界地返回同
![](/icons/40791yi.gif)
对象
![](/icons/40791dou2.gif)
不管是在包含独立
![](/icons/40791break.gif)
条件
![](/icons/40791de.gif)
循环中还是在象 izip
![](/icons/40791kh.gif)
和 imap
![](/icons/40791kh.gif)
这样
![](/icons/40791de.gif)
组合器中
![](/icons/40791dou.gif)
这个迭代器都很有用
![](/icons/40791hanshu.gif)
count
![](/icons/40791kh.gif)
有点类似于 repeat
![](/icons/40791kh.gif)
和 xrange
![](/icons/40791de.gif)
交叉
![](/icons/40791dou2.gif)
count
![](/icons/40791kh.gif)
无界地返回连续整数(以可选
![](/icons/40791de.gif)
参数为开始)
![](/icons/40791dou2.gif)
但是
![](/icons/40791dou.gif)
如果 count
![](/icons/40791kh.gif)
当前不支持溢出到现在正确
![](/icons/40791de.gif)
longs
![](/icons/40791dou.gif)
那么您可能还是要使用 xrange(n,sys.max
![](/icons/40791int.gif)
) ;它并不是完全无界
![](/icons/40791de.gif)
![](/icons/40791dou.gif)
但是对于大多数用途
![](/icons/40791dou.gif)
它实际上是
![](/icons/40791yi.gif)
回事
![](/icons/40791dou2.gif)
类似于 repeat
![](/icons/40791dou.gif)
count
![](/icons/40791kh.gif)
在其它迭代器组合器内部特别有用
![](/icons/40791dou2.gif)
组合
![](/icons/40791hanshu.gif)
我们已经顺便提到了 itertools 中
![](/icons/40791de.gif)
几个实际组合
![](/icons/40791hanshu.gif)
![](/icons/40791if.gif)
ilter
![](/icons/40791kh.gif)
、 izip
![](/icons/40791kh.gif)
和 imap
![](/icons/40791de.gif)
作用就象您会期望从它们相应
![](/icons/40791de.gif)
序列
![](/icons/40791hanshu.gif)
上获得
![](/icons/40791de.gif)
作用
![](/icons/40791if.gif)
ilterfalse
![](/icons/40791kh.gif)
很方便
![](/icons/40791dou.gif)
所以您不需要去掉 lambda 和 def 中
![](/icons/40791de.gif)
谓词
![](/icons/40791hanshu.gif)
(而且这还节省了大量
![](/icons/40791de.gif)
![](/icons/40791hanshu.gif)
![](/icons/40791diaoyong.gif)
开销)
![](/icons/40791dou2.gif)
但是在功能上
![](/icons/40791dou.gif)
您可以将
![](/icons/40791if.gif)
ilterfalse
![](/icons/40791kh.gif)
定义为(大致
![](/icons/40791de.gif)
情况
![](/icons/40791dou.gif)
忽略了 None 谓词):
def
ilterfalse(predicate, iterable):
ilter(lambda predicate: not predicate, iterable)
![](/icons/40791hanshu.gif)
dropwhile
![](/icons/40791kh.gif)
和
![](/icons/40791hanshu.gif)
takewhile
![](/icons/40791kh.gif)
根据谓词对迭代器进行划分
![](/icons/40791dou2.gif)
dropwhile
![](/icons/40791kh.gif)
在直到满足某个谓词 的前忽略所产生
![](/icons/40791de.gif)
元素
![](/icons/40791dou.gif)
takewhile
![](/icons/40791kh.gif)
在满足某个谓词 时就终止
![](/icons/40791dou2.gif)
dropwhile
![](/icons/40791kh.gif)
跳过迭代器
![](/icons/40791de.gif)
不定数目
![](/icons/40791de.gif)
![](/icons/40791chushi.gif)
元素
![](/icons/40791dou.gif)
所以它可能直到某个延迟后才开始迭代
![](/icons/40791dou2.gif)
takewhile
![](/icons/40791kh.gif)
马上开始迭代
![](/icons/40791dou.gif)
但是如果被传入
![](/icons/40791de.gif)
谓词变为真
![](/icons/40791dou.gif)
那么就终止迭代器
![](/icons/40791hanshu.gif)
islice
![](/icons/40791kh.gif)
基本上就是列表分片
![](/icons/40791de.gif)
迭代器版本
![](/icons/40791dou2.gif)
您可以指定开始、停止和步长
![](/icons/40791dou.gif)
就象使用常规
![](/icons/40791de.gif)
片
![](/icons/40791dou2.gif)
如果给定了开始
![](/icons/40791dou.gif)
那么会删除大量元素
![](/icons/40791dou.gif)
直到被传递
![](/icons/40791de.gif)
迭代器到达满足条件
![](/icons/40791de.gif)
元素为止
![](/icons/40791dou2.gif)
这是另
![](/icons/40791yi.gif)
个我认为可以对 Python 进行改进
![](/icons/40791de.gif)
情形 - 迭代器最好只识别片
![](/icons/40791dou.gif)
就象列表所做
![](/icons/40791de.gif)
(作为 islice
![](/icons/40791kh.gif)
行为
![](/icons/40791de.gif)
同义词)
![](/icons/40791dou2.gif)
最后
![](/icons/40791yi.gif)
个
![](/icons/40791hanshu.gif)
starmap
![](/icons/40791kh.gif)
在 imap
![](/icons/40791kh.gif)
基础上略微有些变化
![](/icons/40791dou2.gif)
如果这个作为参数传递
![](/icons/40791de.gif)
![](/icons/40791hanshu.gif)
获取多个参数
![](/icons/40791dou.gif)
那么被传递
![](/icons/40791de.gif)
iterable 会产生大小适合
![](/icons/40791de.gif)
元组
![](/icons/40791dou2.gif)
这基本上和包含多个被传入 iterable
![](/icons/40791de.gif)
imap
![](/icons/40791kh.gif)
相同
![](/icons/40791dou.gif)
只不过它包含先前和 izip
![](/icons/40791kh.gif)
结合在
![](/icons/40791yi.gif)
起
![](/icons/40791de.gif)
iterables 集合
![](/icons/40791dou2.gif)
深入探讨
itertools 中包含
![](/icons/40791de.gif)
![](/icons/40791hanshu.gif)
是
![](/icons/40791yi.gif)
个很好
![](/icons/40791de.gif)
开始
![](/icons/40791dou2.gif)
不使用其它
![](/icons/40791hanshu.gif)
![](/icons/40791dou.gif)
只用这些
![](/icons/40791hanshu.gif)
就可以让 Python
![](/icons/40791chengxu.gif)
员更轻松地利用和组合迭代器
![](/icons/40791dou2.gif)
![](/icons/40791yi.gif)
般说来
![](/icons/40791dou.gif)
迭代器
![](/icons/40791de.gif)
广泛使用对 Python
![](/icons/40791de.gif)
未来无疑是很重要
![](/icons/40791de.gif)
![](/icons/40791dou2.gif)
但是除了过去所包含
![](/icons/40791de.gif)
内容以外
![](/icons/40791dou.gif)
我还要对该模块
![](/icons/40791de.gif)
将来更新提几点建议
![](/icons/40791dou2.gif)
您可以立即很方便地使用这些
![](/icons/40791hanshu.gif)
- 当然
![](/icons/40791dou.gif)
如果它们是后来被包含进来
![](/icons/40791de.gif)
![](/icons/40791dou.gif)
那么名称或接口细节会有所区别
![](/icons/40791yi.gif)
种可能会很通用
![](/icons/40791de.gif)
类别是
![](/icons/40791yi.gif)
些将多个 iterable 作为参数
![](/icons/40791dou.gif)
随后从每个 iterable 产生单独元素
![](/icons/40791de.gif)
![](/icons/40791hanshu.gif)
![](/icons/40791dou2.gif)
和此相对照
![](/icons/40791de.gif)
是
![](/icons/40791dou.gif)
izip
![](/icons/40791kh.gif)
产生元素元组
![](/icons/40791dou.gif)
而 imap
![](/icons/40791kh.gif)
产生从基本元素计算而来
![](/icons/40791de.gif)
值
![](/icons/40791dou2.gif)
我头脑中很清晰
![](/icons/40791de.gif)
两个安排是 chain
![](/icons/40791kh.gif)
和 weave
![](/icons/40791dou2.gif)
第
![](/icons/40791yi.gif)
个在效果上类似于序列并置(但是有点惰性)
![](/icons/40791dou2.gif)
即
![](/icons/40791dou.gif)
在您可能使用
![](/icons/40791de.gif)
纯序列中
![](/icons/40791dou.gif)
例如:
for x in ('a','b','c') + (1, 2, 3):
do_something(x)
对于
![](/icons/40791yi.gif)
般
![](/icons/40791de.gif)
iterables
![](/icons/40791dou.gif)
您可以使用:
for x in chain(iter1, iter2, iter3):
do_something(x)
Python 实现是:
清单 3. chain
![](/icons/40791de.gif)
样本实现
def chain(*iterables):
for iterable in iterables:
for item in iterable:
yield item
使用 iterables
![](/icons/40791dou.gif)
您还可以通过使它们分散排列来组合几个序列
![](/icons/40791dou2.gif)
还没有任何对序列执行这样相同操作
![](/icons/40791de.gif)
内置语法
![](/icons/40791dou.gif)
但是 weave
![](/icons/40791kh.gif)
本身也非常适用于完整
![](/icons/40791de.gif)
序列
![](/icons/40791dou2.gif)
下面是可能
![](/icons/40791de.gif)
实现(Magnus Lie Hetland 提出了 comp.lang.python
![](/icons/40791de.gif)
类似
![](/icons/40791hanshu.gif)
):
清单 4. weave
![](/icons/40791de.gif)
样本实现
def weave(*iterables):
"Intersperse several iterables, until all are exhausted"
iterables = map(iter, iterables)
while iterables:
for i, it in enumerate(iterables):
try:
yield it.next![](/icons/40791kh.gif)
except StopIteration:
del iterables[i]
让我来演示
![](/icons/40791yi.gif)
下 weave
![](/icons/40791de.gif)
行为
![](/icons/40791dou.gif)
![](/icons/40791yinwei.gif)
从实现上看不是很明显:
>>> for x in weave('abc', xrange(4), [10,11,12,13,14]):
... pr
x,
...
a 0 10 b 1 11 c 2 12 13 3 14
即使
![](/icons/40791yi.gif)
些迭代器到达终点
![](/icons/40791dou.gif)
但其余迭代器会继续产生值
![](/icons/40791dou.gif)
直到在某
![](/icons/40791yi.gif)
时刻产生了所有可用
![](/icons/40791de.gif)
值为止
![](/icons/40791dou2.gif)
我将另外只提出
![](/icons/40791yi.gif)
个可行
![](/icons/40791de.gif)
itertools
![](/icons/40791hanshu.gif)
![](/icons/40791dou2.gif)
提出这个
![](/icons/40791hanshu.gif)
主要是受到了构思问题
![](/icons/40791de.gif)
![](/icons/40791hanshu.gif)
编程思路方法
![](/icons/40791de.gif)
启发
![](/icons/40791dou2.gif)
icompose
![](/icons/40791kh.gif)
和上面提出
![](/icons/40791de.gif)
![](/icons/40791hanshu.gif)
ireduce
![](/icons/40791kh.gif)
存在某种对称
![](/icons/40791dou2.gif)
但是在 ireduce
![](/icons/40791kh.gif)
将值
![](/icons/40791de.gif)
(惰性)序列传递给某个
![](/icons/40791hanshu.gif)
并产生每个结果
![](/icons/40791de.gif)
地方
![](/icons/40791dou.gif)
icompose
![](/icons/40791kh.gif)
将
![](/icons/40791hanshu.gif)
序列应用于每个前趋
![](/icons/40791hanshu.gif)
![](/icons/40791de.gif)
返回值
![](/icons/40791dou2.gif)
可以把 ireduce
![](/icons/40791kh.gif)
用于将事件序列传递给长期活动
![](/icons/40791de.gif)
对象
![](/icons/40791dou2.gif)
而 icompose
![](/icons/40791kh.gif)
可能将对象重复地传递给返回新对象
![](/icons/40791de.gif)
赋值
![](/icons/40791hanshu.gif)
![](/icons/40791dou2.gif)
第
![](/icons/40791yi.gif)
种思路方法是相当传统
![](/icons/40791de.gif)
考虑事件
![](/icons/40791de.gif)
OOP 思路方法
![](/icons/40791dou.gif)
而第 2种
![](/icons/40791de.gif)
思路更接近于 FP
![](/icons/40791dou2.gif)
以下是可能
![](/icons/40791de.gif)
icompose
![](/icons/40791kh.gif)
实现:
清单 5. icompose
![](/icons/40791de.gif)
样本实现
def icompose(functions, initval):
currval = initval
for f in functions:
currval = f(currval)
yield currval
结束语
迭代器 - 被认为是惰性序列 - 是功能强大
![](/icons/40791de.gif)
概念
![](/icons/40791dou.gif)
它开启了 Python 编程
![](/icons/40791de.gif)
新样式
![](/icons/40791dou2.gif)
但是在只把迭代器当作数据源和把它作为
![](/icons/40791yi.gif)
种序列来考虑的间存在着微妙
![](/icons/40791de.gif)
差别
![](/icons/40791dou2.gif)
这两种想法本质上哪
![](/icons/40791yi.gif)
种都不见得比另
![](/icons/40791yi.gif)
种更正确
![](/icons/40791dou.gif)
但是后者开创了操作编程事件
![](/icons/40791de.gif)
![](/icons/40791yi.gif)
种组合性
![](/icons/40791de.gif)
简略表达思路方法
![](/icons/40791dou2.gif)
itertools 中
![](/icons/40791de.gif)
组合
![](/icons/40791hanshu.gif)
(尤其是它可能产生
![](/icons/40791de.gif)
![](/icons/40791yi.gif)
些类似于我建议
![](/icons/40791de.gif)
![](/icons/40791hanshu.gif)
)接近于编程
![](/icons/40791de.gif)
声明样式
![](/icons/40791dou2.gif)
对我而言
![](/icons/40791dou.gif)
这些声明样式
![](/icons/40791yi.gif)
般都更不易出错且更强大
延伸阅读
最新评论