簡體   English   中英

Python總結itertools.count?

[英]Python summing itertools.count?

我在使用itertools.count函數時遇到了一些麻煩,我不太明白它的作用。 我希望下面的代碼能夠完成Project Euler問題2

我知道我可以用一個簡單的while循環來編寫它,但有沒有辦法用列表理解來做到這一點? 這個代碼只是凍結,因為我猜它會用count()來無限。 我希望它會在x> MAX之后停止,但我知道這不會發生。 有沒有辦法在下面的生成器表達式中停止計數?

def fib(n):
    if (n <= 1): return 1
    else: return fib(n-1) + fib(n-2)


MAX = 4000000

infiniteFib = (fib(x) for x in count())

s = (x for x in infiniteFib if x < MAX and x % 2 == 0)

print sum(s)

你可以使用takewhile

>>> from itertools import count, takewhile, imap
>>> sum(x for x in takewhile(lambda x: x < 4000000, imap(fib, count())) if x % 2 == 0)
4613732

我們只需要告訴infiniteFib生成器何時停止產生元素。 itertools提供了許多有用的方法來幫助解決這個問題:

less_than_max = itertools.takewhile(lambda x: x<MAX, infiniteFib))
even = itertools.ifilter(lambda x: x%2==0, less_than_max)
print sum(even)

我們得到一個由infiniteFib產生的所有數字的生成器,直到返回的數字大於MAX 然后我們過濾那個生成器,只選擇偶數。 最后我們可以總結結果。

怎么樣:

def fib():
    a, b = 1, 1
    while True:
        yield b
        a, b = b, a+b

sum(f for f in itertools.takewhile(functools.partial(operator.ge, 4000000), fib()) if f % 2 == 0)

或者,將奇偶校驗檢查推送到生成器:

def even_fib():
    a, b = 1, 1
    while True:
        if b % 2 == 0: yield b
        a, b = b, a+b

sum(itertools.takewhile(functools.partial(operator.ge, 4000000), even_fib()))

是的, count()只是繼續前進,這不是你想要的。 列表takewhile /迭代器表達式沒有靈活的退出條件(但請參閱使用takewhile @ DSM解決方案)。

我更喜歡使用while

這是我對Euler 2的舊答案:

def SumEvenFibonacci(limit):
        x = y = 1
        sum = 0
        while (sum <= limit):
                sum += (x + y)
                x, y = x + 2 * y, 2 * x + 3 * y
        return sum

ce = SumEvenFibonacci(4000000)
print ce

這是使用takewhile的另一種解決方案,但非遞歸。 由於遞歸解決方案需要為每個n計算小於n的所有fib s,因此它的速度非常慢。

def fib_gen(only_even=False):
    one = 1
    if not only_even:
        yield one
    two = 1
    if not only_even:
        yield two
    while True:
        next = one + two
        one = two
        two = next
        if only_even:
            if next % 2 == 0:
                yield next
        else:
            yield next

list(itertools.takewhile(lambda x: x < 4000000, fib_gen()))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM