6

リンクリストと同じように機能するPythonクラスでジェネレーターを使用しようとしています。

これが私が言っていることの本当に簡単な例です:

class GeneratorTest():
    def __init__(self, list):
        if list:
            self.elem = list[0]
            if list[1:]:
                self.n = GeneratorTest(list[1:])
            else:
                self.n = None

    def __iter__(self):
        return self

    def next(self):
        my_next = self
        while my_next is not None:
            yield my_next
            my_next = my_next.n

もちろん、これは単なる例ですが、要点を説明するのに十分です。

今、私は次のようなものを呼び出すことができると期待していました:

g = GeneratorTest([1,2,3,4,5])
for x in g:
    print x

そして、最後の値に達したときにサイクルを停止させますが、forループは際限なく続きます。

私はジェネレーターにまったく慣れていないので、ここで見逃している基本的な前提であると確信しています。

問題は、ジェネレーターを作成するのと同じオブジェクトを生成するという事実に関連していますか?GeneratorTestオブジェクトのリストを含むオブジェクトがあれば、これらの各オブジェクトを非常に簡単に返すことができると確信していますが、「ラッパー」オブジェクトなしでこれを機能させる方法があるはずだと思います。

ここで何が欠けていますか?

4

2 に答える 2

4

問題は、next(または、Py3では__next__)ジェネレーターであってはならないことです。外部でその状態とreturn各値を維持する必要があります。毎回新しいジェネレーターを返し続けますが、Pythonはそのジェネレーターを反復処理しないため、ループが実際に実行されることはありません。__iter__これは、最初以外のものを返したいことを意味する場合がありますself(ただし、返すものはすべて、自分自身を返すものが必要です__iter__)。

しかし、良いニュースは、ジェネレーターがこれらのルールを追跡するために正確に存在することです。現在のnextコードをに移動する__iter__と、すべてが機能します-Pythonは、返さ__iter__れるものをすべて繰り返し処理します(予想どおり)。

于 2012-06-25T15:50:54.850 に答える
1

Javaからtreapデータ構造を移植したときに、基本的にこれを行いました。このコードは例として役立つかもしれません: http ://stromberg.dnsalias.org/~strombrg/treap/

これを簡単にする最近のPython機能である「yieldfrom」も参照してください: http ://www.python.org/dev/peps/pep-0380/

treapコードは、からの譲歩なしでそれを行います。

于 2012-06-25T16:03:27.853 に答える