is not needed in for contexts where iteration happens automatically (such as within for loopsit is needed for displaying values here in xthoughand may also be required when list-like behavior or multiple scans are required for objects that produce results on demand in or (more on this aheadnow that you have better understanding of this protocolyou should be able to see how it explains why the enumerate tool introduced in the prior works the way it doese enumerate('spam'enumerate is an iterable too iter(enext(igenerate results with iteration protocol ( ' 'next(ior use list to force generation to run ( ' 'list(enumerate('spam')[( ' ')( ' ')( ' ')( ' ')we don' normally see this machinery because for loops run it for us automatically to step through results in facteverything that scans left to right in python employs the iteration protocol in the same way--including the topic of the next section list comprehensionsa first detailed look now that we've seen how the iteration protocol workslet' turn to one of its most common use cases together with for loopslist comprehensions are one of the most prominent contexts in which the iteration protocol is applied in the previous we learned how to use range to change list as we step across itl [ for in range(len( )) [ + [ this worksbut as mentioned thereit may not be the optimal "best practiceapproach in python todaythe list comprehension expression makes many such prior coding patterns obsolete herefor examplewe can replace the loop with single expression that produces the desired result listl [ for in ll [ iterations and comprehensions