0

格納された値としてリストを使用して辞書でネストされたジェネレーターの理解を使用してみたところ、次の奇妙な(私にとって)動作が観察されました。

Python 2.6.5 (r265:79063, Oct  1 2012, 22:07:21) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> dummy = {1:[1,2,3],2:[2,3,4],3:[3,4,5]}
>>> a = (d for _,d in dummy.iteritems())
>>> a.next()
[1, 2, 3]
>>> a.next()
[2, 3, 4]
>>> a.next()
[3, 4, 5]
>>> a.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

意味あり。以下は(少なくとも私にとっては)そうではありません

>>> aa = (dd for dd in (d for _,d in dummy.iteritems()))
>>> aa.next()
[1, 2, 3]
>>> aa.next()
[2, 3, 4]
>>> aa.next()
[3, 4, 5]
>>> aa.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

(試行された)ネストされたジェネレーターの理解が、ネストされていないバージョンと同じように動作するのはなぜですか?私は、各aa.next()がリストではなく、単一の要素の結果を与えることを期待していました。

4

3 に答える 3

1

内部ジェネレータは、繰り返されるたびに1つの値を返し、各値はリストです。代わりに、実際のネストされた構造を使用する必要があります。

>>> aa = (d3 for dd in (d for _,d in dummy.iteritems()) for d3 in dd)
>>> next(aa)
1
>>> next(aa)
2
>>> next(aa)
3
>>> next(aa)
2
>>> next(aa)
3
>>> next(aa)
4
>>> next(aa)
3
>>> next(aa)
4
>>> next(aa)
5
>>> next(aa)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
于 2012-10-09T01:56:15.907 に答える
1

入れ子にするために、内部ジェネレーターは必要ありません。代わりに、プレーンなネストされた for ループを使用します。

>>> dummy = {1:[1,2,3],2:[2,3,4],3:[3,4,5]}
>>> aa = (dd for _,d in dummy.iteritems() for dd in d)
>>> list(aa)
[1, 2, 3, 2, 3, 4, 3, 4, 5]

これは次のようになります:

def aa(dummy):
    for _, d in dummy.iteritems():
        for dd in d:
            yield dd

print list(aa())

ジェネレーター式を学習する最善の方法は、各ステップで結果を簡単に確認できるように、単純なジェネレーターから始めることです。

于 2012-10-09T01:58:46.827 に答える
0

あなたが考えているように、それは実際には「ネストされた」ジェネレータではありません。

あなたのコードは(おおよそ)以下と同等です:

for dd in (d for _,d in dummy.iteritems()):
    print dd

通常、「ネストされた」は次のようなものを表すために使用されます。

(dd for _, d in dummy.iteritems() for dd in d)
于 2012-10-09T01:54:23.130 に答える