In Python, we use range(0,10) to create a list in memory for 10 numbers.
Python provides another function xrange() that is similar to range() but xrange() returns a sequence object instead of list object. In xrange() all the values are not stored simultaneously in memory. It is a lazy loading based function.
But as per Python documentation, the benefit of xrange() over range() is very minimal in regular scenarios.
As of version 3.1, xrange is deprecated.
Python provides many built-in functions that are surrounded by _ symbol at the start and end of the function name. As per Python documentation, double _ symbol is used for reserved names of functions.
We can use Generator to create Iterators in Python. A Generator is written like a regular function. It can make use of yield statement to return data during the function call. In this way, we can write complex logic that works as an Iterator.
A Generator is more compact than an Iterator due to the fact that _iter_() and next() functions are automatically created in a Generator.
Also within a Generator code, local variables and execution state is saved between multiple calls. Therefore, there is no need to add extra variables like self.index, etc to keep track of iteration.
Generator also increases the readability of the code written in Python. It is a very simple implementation of an Iterator.