我有一个发电机,它将继续提供符合特定公式的数字。为了论证,我们假设这是函数:
# this is not the actual generator, just an example
def Generate():
i = 0
while 1:
yield i
i+=1
然后我想从该生成器获得一个低于某个阈值的数字列表。我试图弄清楚这样做的pythonic方法。我不想编辑函数定义。我意识到你可以使用一个带有截止值的while循环作为条件,但我想知道是否有更好的方法。我试了一下,但很快意识到为什么它不起作用。
l = [x for x in Generate() x<10000] # will go on infinitely
这样做是否有正确的方法。
由于
答案 0 :(得分:11)
创建另一个迭代器的itertools
解决方案:
from itertools import takewhile
l = takewhile(lambda x: x < 10000, generate())
如果您确定需要列表,请将其包裹在list()
中:
l = list(takewhile(lambda x: x < 10000, generate()))
或者,如果你想要一个清单,就像发明车轮一样:
l = []
for x in generate():
if x < 10000:
l.append(x)
else:
break
答案 1 :(得分:0)
只需使用计数器作为无限生成器:
gen=Generate() # your generator function example
l=[gen.next() for i in range(100)]
但是因为它是一个生成器,所以使用生成器表达式:
seq=(gen.next() for i in xrange(100)) #need x in xrange in Python 2.x; 3.x use range
修改强>
好的,然后只需使用控制器:
def controler(gen,limit):
n=gen.next()
while n<limit:
yield n
n=gen.next()
seq=[i for i in controler(Generate(),100)]
答案 2 :(得分:0)
将发电机包裹在另一台发电机内:
def no_more_than(limit):
def limiter(gen):
for item in gen:
if item > limit:
break
yield item
return limiter
def fib():
a,b = 1,1
while 1:
yield a
a,b = b,a+b
cutoff_at_100 = no_more_than(100)
print list(cutoff_at_100(fib()))
打印:
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
答案 3 :(得分:0)
将Generate()
替换为xrange(10000)
答案 4 :(得分:0)
itertools.takewhile
只有在遇到不符合谓词的项目时才会起作用。如果你需要从一个可能无序的可迭代中返回所有值,我建议使用itertools.ifilter
用于Python 2.x,如
from itertools import ifilter
f = ifilter(lambda x: x < 400, gen())
f.next()
这过滤了一个生成器,产生0到400之间的随机整数。
FWIW itertools.ifilter
在Python 3.x中不赞成使用内置filter()
,其迭代语法略有不同
f = filter(lambda x: x < 400, gen())
next(f)
答案 5 :(得分:0)
将其包装在一定范围的zip生成器中:
gen = range(100_000_000_000)
limit = 10
(z[1] for z in zip(range(limit), gen))
zip创建一个元组,这就是z[1]
这可以在for
循环中使用:
for g in (z[1] for z in zip(range(limit), gen)):
print(g)
或者您可以使用lambda:
wrap = lambda gen, limit: (z[1] for z in zip(range(limit), gen))
for g in wrap(gen, 10):
print(g)