2012-09-17 32 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