# Functions Vs. Generators

Want to learn more? I recommend these Python books: Python for Data Analysis, Python Data Science Handbook, and Introduction to Machine Learning with Python.

## Create A Function

# Create a function that def function(names): # For each name in a list of names for name in names: # Returns the name return name

# Create a variable of that function students = function(['Abe', 'Bob', 'Christina', 'Derek', 'Eleanor'])

# Run the function students

'Abe'

Now we have a problem, we were only returned the name of the first student. Why? Because the function only ran the `for name in names`

iteration once!

## Create A Generator

A generator is a function, but instead of returning the `return`

, instead returns an iterator. The generator below is exactly the same as the function above except I have replaced `return`

with `yield`

(which defines whether a function with a regular function or a generator function).

# Create a generator that def generator(names): # For each name in a list of names for name in names: # Yields a generator object yield name

# Same as above, create a variable for the generator students = generator(['Abe', 'Bob', 'Christina', 'Derek', 'Eleanor'])

Everything has been the same so far, but now things get interesting. Above when we ran `students`

when it was a function, it returned one name. However, now that `students`

refers to a generator, it yields a generator object of names!

# Run the generator students

<generator object generator at 0x104837a40>

What can we do this a generator object? A lot! As a generator `students`

will can each student in the list of students:

# Return the next student next(students)

'Abe'

# Return the next student next(students)

'Bob'

# Return the next student next(students)

'Christina'

It is interesting to note that if we use list(students) we can see all the students still remaining in the generator object's iteration:

# List all remaining students in the generator list(students)

['Derek', 'Eleanor']