iterators and generators in section we introduced the for-loop syntax beginning asfor element in iterableand we noted that there are many types of objects in python that qualify as being iterable basic container typessuch as listtupleand setqualify as iterable types furthermorea string can produce an iteration of its charactersa dictionary can produce an iteration of its keysand file can produce an iteration of its lines userdefined types may also support iteration in pythonthe mechanism for iteration is based upon the following conventionsan iterator is an object that manages an iteration through series of values if variableiidentifies an iterator objectthen each call to the built-in functionnext( )produces subsequent element from the underlying serieswith stopiteration exception raised to indicate that there are no further elements an iterable is an objectobjthat produces an iterator via the syntax iter(objby these definitionsan instance of list is an iterablebut not itself an iterator with data [ ]it is not legal to call next(datahoweveran iterator object can be produced with syntaxi iter(data)and then each subsequent call to next(iwill return an element of that list the for-loop syntax in python simply automates this processcreating an iterator for the give iterableand then repeatedly calling for the next element until catching the stopiteration exception more generallyit is possible to create multiple iterators based upon the same iterable objectwith each iterator maintaining its own state of progress howeveriterators typically maintain their state with indirect reference back to the original collection of elements for examplecalling iter(dataon list instance produces an instance of the list iterator class that iterator does not store its own copy of the list of elements insteadit maintains current index into the original listrepresenting the next element to be reported thereforeif the contents of the original list are modified after the iterator is constructedbut before the iteration is completethe iterator will be reporting the updated contents of the list python also supports functions and classes that produce an implicit iterable series of valuesthat iswithout constructing data structure to store all of its values at once for examplethe call range( does not return list of numbersit returns range object that is iterable this object generates the million values one at timeand only as needed such lazy evaluation technique has great advantage in the case of rangeit allows loop of the formfor in range( ):to execute without setting aside memory for storing one million values alsoif such loop were to be interrupted in some fashionno time will have been spent computing unused values of the range