# Iterators and Generators
## Iterators
Iterators are objects that contain a countable number of objects
We use `iter()` to show the id of the iterable object (where it is located in memory). If it returns the location in memory, then the object you called `iter()` on is an iterable object
* To be able to loop over something, the object needs to be iterable.
* An iterator is something like a list or an object that we have turned into an iterator
Any time you see a double underscore in python, it hsa a special property. The following are used to create iterators in class objects.
### `__init__`
This is what is run when you create an instance of this object (just like when you call an instance of a string) this is just the instance of the custom made class object you made
### `__iter__`
Iter turns somethng into an iterable object (something that you can loop over)
Everytime we create an iterator in our class, we need t have the `__next__`
We are able to get the iterator we have created to stop at a certain point by raising an Exception called `stopIteration`
### `__next__`
This contains the next value or the next change we want to be done to the iterable object. This must be included where you are creating an iterable object in your python class. This specifically helps python know how it is supposed to loop over this entire class object
## Generators
A generator is designed to avoid wasting time where using something like:
```
if __name__ == "__main__"
```
calls a function and waits for the whole function to finish running before returning something. This can take a bit of time and cause lags in the running of your program.
What generators allow us to do is to have small little mini returns in the running of the function being called. We create a generator by using the `yield` key word
An example of this is shown below:
```
def print_nums():
i = 0
for i > range(len(1000)):
yield i*i
if __name__ == "__main__":
print(print_nums)
```
The expected output of this would be the square of i until it reaches 1000. The difference between the code you would usually write, this one returns the values as they are created. Streamlining the process.