1

我想通过重复调用一个函数来生成一个列表,直到该函数返回一个预定义的值。

myList = [i,r = foo() while i==0]

myList = [r1, r2, r3, r4...] as long as returned i value is == 0

有没有办法使用列表理解来做到这一点?

4

4 回答 4

1
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())
于 2013-10-30T15:44:40.457 回答
0

我不认为有一个单一的衬里。但是,通过定义一个简单的生成器来包装任何给定的类似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))
于 2013-10-30T15:51:55.467 回答
0

不,你不能那样做。列表推导式支持的唯一关键字是for, if, 和elselambda当然还有)。

所以,你必须做一个多线解决方案。但是,无需定义包装函数。这将正常工作:

mylist = []
while True:   
    i, r = foo()
    if i: break
    mylist.append(r)

最终,mylist会拥有你想要的一切。

于 2013-10-30T15:57:06.937 回答
0

不建议这样做,但是...

>>> 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()))
于 2013-10-30T16:08:25.970 回答