Use of yield with a dict comprehension

前端 未结 4 842
醉梦人生
醉梦人生 2021-02-07 01:53

As a contrived example:

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

and

4条回答
  •  闹比i
    闹比i (楼主)
    2021-02-07 02:44

    First of all, what does yield return? The answer in this case is None, because yield returns the parameter passed to next(), which is nothing in this case (list doesn't pass anything to next).

    Now here's your answer:

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

    The dict comprehension is turned into a generator, because you used yield in a function body context! This means that the whole thing isn't evaluated until it's passed into list.

    So here's what happens:

    1. list calls next(mydict).
    2. Yield returns ''.join([item, 's']) to list and freezes the comprehension.
    3. list calls next(mydict).
    4. The comprehension resumes and assigns the result of yield (None) to item in the dictionary and starts a new comprehension iteration.
    5. Go back to 1.

    And at last the actual generator object returns the temporary in the body, which was the dict. Why this happens is unknown to me, and it's probably not documented behaviour either.

提交回复
热议问题