22

不自然な例として:

myset = set(['a', 'b', 'c', 'd'])
mydict = {item: (yield ''.join([item, 's'])) for item in myset}

そしてlist(mydict)与える:

['as', 'cs', 'bs', 'ds', {'a': None, 'b': None, 'c': None, 'd': None}]

ここでは何が起きるのですか?何をしyieldますか?そして、この振る舞いは、どのような表現が続くかに関係なく一貫していますyieldか?

注:実行mydict = {item: ''.join([item, 's']) for item in myset}すると辞書が作成{'a': 'as', 'b': 'bs', 'c': 'cs', 'd': 'ds'}されることはわかっています。これは、私がここで実行しようとしていることのようです。

4

4 に答える 4

12

まず第一に、何がyield返されますか?この場合の答えは、に渡されたパラメータを返すNoneためです。この場合は何も返されません(に何も渡されません)。yieldnext()listnext

これがあなたの答えです:

>>> myset = set(['a', 'b', 'c', 'd'])
>>> mydict = {item: (yield ''.join([item, 's'])) for item in myset}
>>> mydict
<generator object <dictcomp> at 0x0222BB20>

yield関数本体のコンテキストで使用したため、dictの理解はジェネレーターに変わります!これは、に渡されるまですべてが評価されないことを意味しlistます。

だからここに何が起こるかです:

  1. listを呼び出しますnext(mydict)
  2. 利回りは理解に戻り、理解''.join([item, 's'])list凍結します。
  3. listを呼び出しますnext(mydict)
  4. yield理解が再開され、 (None)の結果が辞書に割り当てられitem、新しい理解の反復が開始されます。
  5. 1に戻ります。

そして最後に、実際のジェネレーターオブジェクトは本体に一時的なものを返します。これは。でしたdict。なぜこれが起こるのかは私にはわかりませんし、おそらく文書化された振る舞いでもありません。

于 2012-09-10T19:34:20.967 に答える
4

yieldそれはあなたの素晴らしい辞書理解をジェネレータ式に変えていると思います。したがって、ジェネレーターを反復処理している場合、yieldはasbs...に見える要素を「生成」しますが、ステートメントは。をyield ...返しますNone。したがって、1日の終わりに、次のような辞書が作成されます{'a': None, 'b': None, ...}

私を混乱させる部分は、辞書が実際に最後に生成される理由です。この振る舞いは実際には標準で明確に定義されていないと思いますが、それについては間違っている可能性があります。

興味深いことに、リスト内包表記でこれを試してみると、Pythonは次のように文句を言います。

>>> a = [(yield i) for i in myset]
  File "<stdin>", line 1
SyntaxError: 'yield' outside function

しかし、ジェネレーターでは問題ありません(どうやら)。

于 2012-09-10T19:23:20.553 に答える
2

見つけた!^ _ ^

通常の生活では、表現

print {item: (yield ''.join([item, 's'])) for item in myset} 

このように評価します:

def d(myset):
    result = {}
    for item in myset:
        result[item] = (''.join([item, 's']))
    yield result

print d(myset).next()

なぜyield result代わりにreturn result?次のようなネストされたリスト内包表記*をサポートする必要があると思います。

print {i: f.lower() for i in nums for f in fruit}  # yes, it's works

それで、このコードのようになりますか?

def d(myset):
    result = {}
    for item in myset:
        result[item] = (yield ''.join([item, 's']))
    yield result

>>> print list(d(myset))
['as', 'cs', 'bs', 'ds', {'a': None, 'b': None, 'c': None, 'd': None}]

最初はのすべての値が返さ''.join([item, 's'])れ、最後はdictが返されresultます。yield式の値はNone、であるため、の値もです。resultNone

*ネストされたリスト内包表記の評価のより正確な解釈:

print {i: f.lower() for i in nums for f in fruit}

# eval like this:

result = {}
for i, f in product(nums, fruit): # product from itertools
    key, value = (i, f.lower())
    result[key] = value
print result
于 2012-09-10T21:53:20.890 に答える
0

私はあなたのコードがこれの類似性を実行しなければならないと思います:

def d(myset):
    for item in myset:
        yield item, (yield ''.join([item, 's']))

d(myset)

まず、評価されyield ''.join([item, 's']ます(そして、「as」、「cs」などを返します)。ジェネレータに返送されるため、yield式の値はNoneです。yield item, None次に、タプル('a'、None)、('b'、None)を返すeval 。

ので、私は持っています:

>>> list(d(myset))
['as', ('a', None), 'cs', ('c', None), 'bs', ('b', None), 'ds', ('d', None)]

次に何が起こるか、私にはわかりません。

于 2012-09-10T21:09:21.287 に答える