Python函数,它产生生成器和聚合结果

时间:2017-01-29 23:55:01

标签: python generator

使用生成聚合结果的生成器的Pythonic方法是什么?在元代码中,这样的东西(但不是真实的,因为我的Python版本不支持混合产量和返回):

def produce():
    total = 0
    for item in find_all():
        total += 1
        yield item

    return total

在我看来,我可以:

  1. 不要使produce()成为生成器,而是将其传递回调函数以调用每个item
  2. 每个yield,以及yield汇总到目前为止。我宁愿不用每一次收益计算中间结果,只有在完成时。
  3. dict作为参数发送到produce(),其中将填充汇总结果。
  4. 使用全局来存储汇总结果。
  5. 所有这些看起来都不太吸引人......

    NB。 total是一个简单的例子,我的实际代码需要复杂的聚合。我需要在produce()完成之前获得中间结果,因此需要一个生成器。

3 个答案:

答案 0 :(得分:3)

也许你不应该使用生成器而是使用迭代器。

def findall():  # no idea what your "find_all" does so I use this instead. :-)
    yield 1
    yield 2
    yield 3

class Produce(object):
    def __init__(self, iterable):
        self._it = iterable
        self.total = 0

    def __iter__(self):
        return self

    def __next__(self):
        self.total += 1
        return next(self._it)

    next = __next__  # only necessary for python2 compatibility

也许最好通过一个例子看到这个:

>>> it = Produce(findall())
>>> it.total
0
>>> next(it)
1
>>> next(it)
2
>>> it.total
2

答案 1 :(得分:1)

您可以使用enumerate来计算内容,例如

i=0
for i,v in enumerate(range(10), 1 ):
    print(v)
print("total",i)

(注意枚举的起始值)

对于更复杂的东西,你可以使用相同的原理,make产生一个产生两个值的生成器,在迭代中忽略一个,并在完成后再使用它。

其他替代方法是传递可修改的对象,例如

def produce(mem):
    t=0
    for x in range(10):
        t+=1
        yield x
    mem.append(t)

aggregate=[]
for x in produce(aggregate):
    print(x)
print("total",aggregate[0])

在任何一种情况下,此示例的结果都相同

0
1
2
3
4
5
6
7
8
9
total 10

答案 2 :(得分:0)

我错过了什么吗?为什么不:

def produce():
   total = 0
   for item in find_all():
       total += 1
       yield item

    yield total