advanced programming techniques identical to list comprehensionsthe difference being that they are enclosed in parentheses rather than brackets here are their syntaxes(expression for item in iterable(expression for item in iterable if conditionin the preceding we created some iterator methods using yield expressions here are two equivalent code snippets that show how simple for in loop containing yield expression can be coded as generatordef items_in_key_order( )for key in sorted( )yield keyd[keydef items_in_key_order( )return ((keyd[key]for key in sorted( )both functions return generator that produces list of key-value items for the given dictionary if we need all the items in one go we can pass the generator returned by the functions to list(or tuple()otherwisewe can iterate over the generator to retrieve items as we need them generators provide means of performing lazy evaluationwhich means that they compute only the values that are actually needed this can be more efficient thansaycomputing very large list in one go some generators produce as many values as we ask for--without any upper limit for exampledef quarters(next_quarter= )while trueyield next_quarter next_quarter + this function will return and so onforever here is how we could use the generatorresult [for in quarters()result append(xif > break the break statement is essential--without it the for in loop will never finish at the end the result list is [ every time we call quarters(we get back generator that starts at and increments by but what if we want to reset the generator' current valueit is possible to pass value into generatoras this new version of the generator function showsdef quarters(next_quarter= )while true