用于Python 2.x中循环迭代的Deferred_output

时间:2012-03-11 16:05:08

标签: python python-3.x python-2.x

Here我找到了一个很好的方法,如何使用延迟输出的技术计算数字序列。

我决定使用相同的技术来解决Project Euler中的第二个问题。

代码:

#Answer: 4613732
from itertools import *
import operator

seeds = [1,2]

def deferred_output():
    for i in output:
        yield i

result,a1,a2 = tee(deferred_output(),3)
paired = map(operator.add,a1,islice(a2,1,None))
output = chain(seeds,paired)

cropped = takewhile((4000000).__gt__,result)
evened = filter(lambda x: x%2==0,cropped)

print(sum(evened))

代码在Python 3.x中完美运行

但是当我尝试在Python 2.x中运行它时,出现以下错误:

Traceback (most recent call last):
  File "C:\Documents and Settings\Oleg\Мои документы\_Мои документы\_SyncedWithFlashDrive\Программирование\Project Euler\2\1.py", line 14, in <module>
    paired = map(operator.add,a1,islice(a2,1,None))
  File "C:\Documents and Settings\Oleg\Мои документы\_Мои документы\_SyncedWithFlashDrive\Программирование\Project Euler\2\1.py", line 9, in deferred_output
    for i in output:
NameError: global name 'output' is not defined

这意味着延迟输出在Python 2.x中不起作用

为什么?

1 个答案:

答案 0 :(得分:2)

以下代码有效:

from itertools import *                                                         
import operator                                                                 

seeds = [1,2]                                                                   

def deffered_output():                                                          
    for i in output:                                                            
        yield i

result,a1,a2 = tee(deffered_output(),3)
paired = imap(operator.add,a1,islice(a2,1,None))   # change 2 (imap)
output = chain(seeds,paired)

cropped = takewhile(lambda x: x <= 4000000,result) # change 1 (lambda)
evened = filter(lambda x: x%2==0,cropped)

print(sum(evened))

我需要做两处修改:

首先,takewhile的参数需要是lambda,因为2.7中的整数不具有__gt__等方法。

第二,更重要的是,python 3中的map()是懒惰的 - 它返回一个后来完成工作的生成器。相比之下,在python 2.7中,它非常渴望 - 它可以直接完成工作并返回一个列表。

所以,在python 2.7中,map()触发代码的评估,代码通过各种生成器回调,直到它评估deffered_output()函数。这一切都发生在之前定义output的行。所以有一个错误,因为output未定义。

然而,在python 3中(或在python 2.7中使用imap()时)该行创建了另一个生成器,在sum()中评估事物之前,它实际上并没有完成工作(和到那时,output已定义,因此可以对deffered_output进行评估。

如果不清楚,那么您需要在python中了解有关generators的更多信息。

ps并不重要,但它让我疯狂地看着它:它推迟了#34;而不是&#34; deffered&#34;!