Generators are implemented with syntax very similar to functions, but instead of returning values, a yield statement is executed to indicate each element in the series
Consider the goal of computing all factors of a positive integer. A traditional function might return a list contating all factors, implemeted as follows:
def factors(n): # traditional function that computes factors
results = [] # store factors in a new list
for k in range(1, n+1):
if n % k == 0: # divides evenly, thus k is a factor
results.append(k) # add k to the list of factors