我想通过重复调用一个函数来生成一个列表,直到该函数返回一个预定义的值。
myList = [i,r = foo() while i==0]
myList = [r1, r2, r3, r4...] as long as returned i value is == 0
有没有办法使用列表理解来做到这一点?
我想通过重复调用一个函数来生成一个列表,直到该函数返回一个预定义的值。
myList = [i,r = foo() while i==0]
myList = [r1, r2, r3, r4...] as long as returned i value is == 0
有没有办法使用列表理解来做到这一点?
def stop_iteration():
raise StopIteration
如果foo()
是生成器:
myList = list((i,r) if i != 0 else stop_iteration() for (i,r) in foo())
别的:
def foo_generator():
i,r = foo()
while i != 0:
yield i,r
i,r = foo()
myList = list(foo_generator())
我不认为有一个单一的衬里。但是,通过定义一个简单的生成器来包装任何给定的类似foo
函数,您就可以做到。
TEST = [(0, 0), (1, 0), (2, 1), (3, 0)]
def foo():
return TEST.pop(0)
def foo_wrapper(foo_like):
r, i = foo_like()
while i == 0:
yield r
r, i = foo_like()
print list(foo_wrapper(foo))
不,你不能那样做。列表推导式支持的唯一关键字是for
, if
, 和else
(lambda
当然还有)。
所以,你必须做一个多线解决方案。但是,无需定义包装函数。这将正常工作:
mylist = []
while True:
i, r = foo()
if i: break
mylist.append(r)
最终,mylist
会拥有你想要的一切。
不建议这样做,但是...
>>> def notyet(predicate):
if predicate:
raise StopIteration
return True
>>> # note that below we're wrapping a generator expression in a
>>> # call to `list` so that when `StopIteration` is raised your
>>> # program won't terminate.
>>> xs = list((i, r) for (i, r) in foo() if notyet(i!=0))
>>> # if we try this instead, your program will hit the buffers
>>> # when the predicate is satisfied.
>>> xs = [(i, r) for (i, r) in foo() if notyet(i!=0)]
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
xs = [(i, r) for (i, r) in foo() if notyet(i!=0)]
File "<pyshell#3>", line 3, in notyet
raise StopIteration
StopIteration
在这种情况下使用 itertools.takewhile 会更好。
>>> from itertools import takewhile
>>> xs = list(takewhile(lambda (i, r): i!=0, foo()))