As a contrived example:
myset = set(['a', 'b', 'c', 'd'])
mydict = {item: (yield ''.join([item, 's'])) for item in myset}
and list(mydict) gives:
['as', 'cs', 'bs', 'ds', {'a': None, 'b': None, 'c': None, 'd': None}]
What happens here? What does yield do? And is this behavior consistent no matter what expression follows yield?
Note: I know that doing mydict = {item: ''.join([item, 's']) for item in myset} would give the dictionary {'a': 'as', 'b': 'bs', 'c': 'cs', 'd': 'ds'}, which seems to be what I am trying to do here.
First of all, what does
yieldreturn? The answer in this case isNone, becauseyieldreturns the parameter passed tonext(), which is nothing in this case (listdoesn’t pass anything tonext).Now here’s your answer:
The dict comprehension is turned into a generator, because you used
yieldin a function body context! This means that the whole thing isn’t evaluated until it’s passed intolist.So here’s what happens:
listcallsnext(mydict).''.join([item, 's'])tolistand freezes the comprehension.listcallsnext(mydict).yield(None) toitemin the dictionary and starts a new comprehension iteration.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.