for sub in line split(',')yield sub upper(tuple(ups('aaa,bbb,ccc')('aaa''bbb''ccc'substring generator all iteration contexts {is for (isin enumerate(ups('aaa,bbb,ccc')){ 'aaa' 'bbb' 'ccc'in moment we'll see the same assets for generator expressions-- tool that trades function flexibility for comprehension conciseness later in this we'll also see that generators can sometimes make the impossible possibleby producing components of result sets that would be far too large to create all at once firstthoughlet' explore some advanced generator function features extended generator function protocolsend versus next in python send method was added to the generator function protocol the send method advances to the next item in the series of resultsjust like __next__but also provides way for the caller to communicate with the generatorto affect its operation technicallyyield is now an expression form that returns the item passed to sendnot statement (though it can be called either way--as yield xor (yield )the expression must be enclosed in parentheses unless it' the only item on the right side of the assignment statement for examplex yield is okas is (yield when this extra protocol is usedvalues are sent into generator by calling send(valuethe generator' code is then resumedand the yield expression in the generator returns the value passed to send if the regular __next__(method (or its next(gequivalentis called to advancethe yield simply returns none for exampledef gen()for in range( ) yield print(xg gen(next( send( send( next(gnone must call next(firstto start generator advanceand send value to yield expression next(and __next__(send none comprehensions and generations