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

いいえ、それはできません。リスト内包表記がサポートする唯一のキーワードは、、、forおよびif(elseそしてlambdaもちろん) です。

したがって、複数行のソリューションを実行する必要があります。ただし、ラッパー関数を定義する必要はありません。これはうまくいきます:

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

最後に、mylistあなたが望むすべてのものを手に入れます。

于 2013-10-30T15:57:06.937 に答える
0

そのためのワンライナーはないと思います。ただし、特定のfoo-like 関数をラップする単純なジェネレーターを定義することで、それを行うことができます。

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

これはお勧めできませんが...

>>> 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 に答える