尝试创建生成器对象但获取不响应生成器调用的函数对象

时间:2015-09-25 19:48:57

标签: python generator

我正在尝试编写一个无限生成器,它将重复每个正整数n次。例如,如果我创建f = inf_repeat(3),则将f的输出打印10次会导致:

1 1 1 2 2 2 3 3 3 4

我很亲密但不完全在那里。这就是我所拥有的:

    # courtesy of http://stackoverflow.com/questions/279561/what-is-the-python-equivalent-of-static-variables-inside-a-function
    # a generator that yields items instead of returning a list
    def static_var(varname, value):
        def decorate(func):
            setattr(func, varname, value)
            return func
        return decorate

    def inf_repeat(k):
        count_limit = k
        @static_var("counter", 0)
        @static_var("number", 0)
        def func():
            while True:
                if  func.counter == count_limit:
                    func.counter = 0
                    func.number += 1
                func.counter += 1
                yield func.number
        return func

我的问题是,这并不像迭代器那样完全。以下命令有效:

f3 = inf_repeat(3)
print next(f3())

但是必须用parens打电话给f3是令人恼火的。我希望能够使用我见过的标准迭代器语法,例如:

print(f3.next())

new_list = [iter(f3)]*5

在我的功能中需要修改什么来达到这一点?看看各种生成器教程,似乎yield足以创建一个生成器,但显然情况并非如此。

此外,我没有使用模块的目标。我查了一下itertools,但是如果没有这些代码,我可能会错过一些可以做我想做的事情吗?

4 个答案:

答案 0 :(得分:1)

您只需要在某个时刻调用生成器对象(您称之为f3)。您可以在创建它时调用它:

f3 = inf_repeat(3)()

甚至在inf_repeat

# change last line to this
return func()

在函数中放置yield使它成为一个生成函数---也就是说,一个函数在被调用时返回一个生成器。如果你想获得生成器,你需要在某个时刻调用你的生成器函数。

顺便说一下,你的实施是不必要的复杂。如果没有所有装饰器和嵌套函数,您可以更简单地获得所需的行为:

def inf_repeat(k):
    number = k
    while True:
        yield number // k
        number += 1

然后:

>>> list(itertools.islice(inf_repeat(3), 10))
[1, 1, 1, 2, 2, 2, 3, 3, 3, 4]
>>> list(itertools.islice(inf_repeat(4), 13))
[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4]

答案 1 :(得分:1)

这是一个简单的解决方案:

stage.addChild(playBtn);
playBtn.x = 0;
playBtn.y = stage.stageHeight/2;;
playBtn.addEventListener(MouseEvent.CLICK, playGame);

这是使用itertools的解决方案:

def inf_repeat(N):
    i = 1
    while True:
        for n in range(N):
            yield i
        i += 1

# Testing:
f = inf_repeat(3)
for j in range(10):
    print f.next()

答案 2 :(得分:1)

使用itertools的另一种解决方案

import itertools as it

def inf_repeat(k):
    for i in it.count(1):
        for j in [i]*k:
            yield j

for n in inf_repeat(3): print n

产生

1
1
1
2
2
2
...

答案 3 :(得分:1)

def f(n):
    i = 0
    while True:
        yield i // n
        i += 1
相关问题