我正在尝试编写一个无限生成器,它将重复每个正整数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
,但是如果没有这些代码,我可能会错过一些可以做我想做的事情吗?
答案 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