具有外部中断条件的Python生成器

时间:2013-02-20 14:00:19

标签: python generator

我需要迭代n(= 5,f.i。)整数的递增序列x,找到函数f(* x)返回True的所有序列。

假设如果特定y的f_n(* y)为假,则对于z_i> = y_i的任何z,f_n(* z)id为False。因此f_n在其所有参数中都是单调的。

这种生成器函数可以按以下方式使用,以确定具有平方和<1的整数的所有递增序列。 100

for sequence in generate_sequences(5):
   if sum_squares_is_at_least(sequence, 100):
       # some code to trigger the breaking of the generator loop
   else:
       print sequence

澄清: 这里的问题是我们需要单独迭代n个元素。最初,我们迭代[1,1,1,1,1]到[1,1,1,1,x],然后我们必须继续[1,1,1,2,2]到[1, 1,1,2,y],最终以[a,b,c,d,e]结尾。似乎生成器应该看起来像这样,但是如果需要,需要一些代码来打破for和/或while循环(在外部确定):

def generate_sequences(length, minimum = 1):
    if length == []:
        yield []

    else: 
        element = minimum
        while True:

            for sequence in generate_sequences(length - 1, element):
                yield element + [sequence]

            element += 1

实施例: 对于n = 3,并且平方和不大于20,将生成以下序列: [1,1,1],[1,1,2],[1,1,3],[1,1,4],[1,2,2],[1,2,3],[1] ,3,3],[2,2,2],[2,2,3]

请注意,在一般情况下,我不能使用4是每个元素的上限的信息。这也会严重影响更大范例的运行时间。

3 个答案:

答案 0 :(得分:1)

您在寻找itertools.takewhile吗?

>>> from itertools import takewhile
>>> def gen():  #infinite generator
...    i=0
...    while True:
...       yield range(i,i+5)
...       i = i+1
... 
>>> [ x for x in takewhile( lambda x:sum(x)<20, gen() ) ]
[[0, 1, 2, 3, 4], [1, 2, 3, 4, 5]]
>>> 

答案 1 :(得分:0)

import itertools as it

it.takewhile(lambda x: sum_squares_is_at_least(x, 100), generate_sequences(5))

如果你现在确定generate_sequences中的 5 ,那么只要它被调用就让它yield

def generate_sequences():
    i = 0 # or anything
    while True:
        yield [i, i] # or anything
        i = i + 1 # or anything

然后以这种方式使用它:

it.takewhile(lambda x: sum_squares_is_at_least(x, 100), generate_sequences())

答案 2 :(得分:0)

我会通过从给定列表开始然后附加另一个数字(使用逻辑来防止超过正方形目标)来递归来解决它。

def makegen(N): #make a generator with max sumSquares: N
    def gen(l=[]): #empty list is valid with sum == 0
        yield l
        if l:
            i = l[-1] #keep it sorted to only include combinations not permutations
        else:
            i = 1 #only first iteration
        sumsquare = sum(x*x for x in l) #find out how much more we can add
        while sumsquare + i*i < N: #increase the appended number until we exceed target
            for x in gen(l+[i]): #recurse with appended list
                yield x
            i += 1
    return gen

以下列方式调用我们的生成器生成器(tee hee:D)允许我们拥有任何我们想要的最大平方和

for x in makegen(26)():
    print x