the usual generator usage contextsdef both( )yield from range(nyield from ( * for in range( )list(both( )[ join(str(ifor in both( )' in more advanced roleshoweverthis extension allows subgenerators to receive sent and thrown values directly from the calling scopeand return final value to the outer generator the net effect is to allow such generators to be split into multiple subgenerators much as single function can be split into multiple subfunctions since this is only available in and laterand is beyond this generator coverage in generalwe'll defer to python ' manuals for additional details for an additional yield from examplealso see the solution to this part' exercise described at the end of generation in built-in typestoolsand classes finallyalthough we've focused on coding value generators ourselves in this sectiondon' forget that many built-in types behave in similar ways--as we saw in for exampledictionaries are iterables with iterators that produce keys on each iterationd {' ': ' ': ' ': iter(dnext( 'cnext( 'blike the values produced by handcoded generatorsdictionary keys may be iterated over both manually and with automatic iteration tools including for loopsmap callslist comprehensionsand the many other contexts we met in for key in dprint(keyd[key] as we've also seenfor file iteratorspython simply loads lines from the file on demandfor line in open('temp txt')print(lineend='' comprehensions and generations