因此,一个简单的发电机在Python(没有相应的错误检查):
def foldr(op, lst):
l, x = reversed(list(lst)), None
for i in l:
if not x:
x = i
continue
x = op(x, i)
yield x
如:
>>> from operator import mul
>>> for i in foldr(mul, [1,2,3,4]):
... print i
24
24
12
几乎与“大致等价”实现的reduce i n个文件:
def foldr(function, iterable, initializer=None):
it = reversed(list(iterable))
if initializer is None:
try:
initializer = next(it)
except StopIteration:
raise TypeError('foldr() of empty sequence with no initial value')
accum_value = initializer
for x in it:
accum_value = function(accum_value, x)
yield accum_value
[编辑] 所以纯粹的心态和非常实用价值不大的运动,这是可能的,只要有功能之间的一些合作,你一个折叠推迟...例如:
class Defer(object):
def __init__(self, func, *args):
self.func = func
self.args = args
def __bool__(self):
return self.func(*self.args)
def __int__(self):
return self.func(*self.args)
def foldr(function, iterable, initializer):
it = iter(iterable)
try:
return function(next(it), Defer(foldr, function, it, initializer))
except StopIteration:
return initializer
这时只要功能转换成可以推迟计算正确的类型,但是这不会与本地运营商合作,所以不知道这是多么有用真的是:
>>> print(foldr(lambda a, b: int(a)*int(b), [1,2,3,4], 1))
24
定义永远发生器:
from itertools import repeat
def forever():
yield False
yield True
for i in repeat(False):
yield i
跨越无限列表折叠or
,返回时,发现一个真正的
>>> print(foldr(lambda a, b: bool(a) or bool(b), forever(), False))
True
我认为为了做到这一点,你的发电机必须“产生”一个发电机,它产生一个发电机......如果传递的参数是一个空列表,那么yield就是初始值...这听起来有点令人头痛,坦率地说...... Python在递归方面很好,只要它具有合理的深度,但我不完全确定递归和生成器在一起很好地发挥了... – twalberg 2015-03-31 16:58:30
haskell foldr的定义只是简化,foldl将在无限列表中失败。 – AChampion 2015-03-31 17:57:23
Python的'reduce'是左对齐的,所以它就像Haskell的'foldl'(注意素数)。是的,'foldl'及其变体将在无限的列表上失败,这就是为什么人们可能希望使用正确的折叠。 – 2015-03-31 18:04:35