2012-09-17 35 views
2

我有一個發電機,並希望找出它產生的第一個值比X大什麼方法做到這一點如下,但它似乎相當冗長(它讀起來像重複自己)。優雅的方式來計算第一個發電機的結果比X大

def long_winded(gen,X) 
    n = next(gen) 
    while n < X: n=next(gen) 
    return n 

我想寫什麼更多的東西簡單:

short_broken(gen,X): 
    while next(gen)<X: pass 
    return next(gen)   # returns the SECOND value larger than X, as gen is called again 
short_broken2(gen,X): 
    while n = next(gen)<X: pass # Not python syntax! 
    return n 

是否有返回相同的結果pythonically,簡潔的方式?

回答

5
def short2(gen,X): 
    for x in gen: 
     if x > X: 
      return x 

或爲1班輪(我更喜歡迭代工具變體):

def short3(gen,X): 
    return next(x for x in gen if x > X) 

我原來的答覆 - 只爲後人留下的緣故

我不一定主張這種方法更好,但可以使用遞歸函數:

def short(gen,X): 
    n = next(gen) 
    return n if n>X else short(gen,X) 
+3

這是優雅的,但一個壞主意,如果你將會有發電機,你必須檢查一千多個元素(或者比你設定的最大遞歸限制更多)。 – Wilduck

+0

啊哈!這是遞歸的明顯候選者。 :)但不幸@維爾德克的觀點是一個很好的觀點。 –

+0

@ Wilduck的觀點絕對是一個很好的觀點 - 爲什麼我以「我不一定主張這種方法更好」作爲我的評論的前言?......這是一種弱言 - 「我懷疑我會用這在我的代碼「。 – mgilson

8
from itertools import dropwhile 

def first_result_larger_than_x(gen, X): 
    return next(dropwhile(lambda n: n <= X, gen)) 

要注意,從OP您的代碼示例實際上返回的第一個結果大於或等於 X.我已經糾正了,在此代碼示例,但如果這是你真正想要的東西,變化<=改爲<

+0

謝謝,像往常一樣itertools是業務!我確實比標題中說的要多(我懷疑這對實際答案無關緊要:))。 –

+0

Itertools似乎在這裏過度殺傷...'下一個(如果x> X,X代表x)'本質上是沒有itertools和lambda函數的相同的東西... – mgilson