Running average in Python
Question: Is there a pythonic way to **build up a list that contains a running average**
of some function?

After reading a fun little piece about [Martians, black boxes, and the Cauchy
distribution](http://www.johndcook.com/Cauchy%5Festimation.html), I thought it
would be fun to calculate a running average of the Cauchy distribution myself:

    
    
    import math 
    import random
    
    def cauchy(location, scale):
        p = 0.0
        while p == 0.0:
            p = random.random()
        return location + scale*math.tan(math.pi*(p - 0.5))
    
    # is this next block of code a good way to populate running_avg?
    sum = 0
    count = 0
    max = 10
    running_avg = []
    while count < max:
        num = cauchy(3,1)
        sum += num
        count += 1
        running_avg.append(sum/count)
    
    print running_avg     # or do something else with it, besides printing
    

I think that this approach works, but I'm curious if there might be a more
elegant approach to building up that `running_avg` list than using loops and
counters (e.g. [list
comprehensions](http://docs.python.org/tutorial/datastructures.html#list-
comprehensions)).

There are some related questions, but they address more complicated problems
(small window size, exponential weighting) or aren't specific to Python:

  * <http://stackoverflow.com/questions/488670/calculate-exponential-moving-average-in-python>
  * <http://stackoverflow.com/questions/1174984/how-to-efficiently-calculate-a-running-standard-deviation>
  * <http://stackoverflow.com/questions/1319891/calculating-the-moving-average-of-a-list>


Answer: You could write a generator:

    
    
    def running_average():
      sum = 0
      count = 0
      while True:
        sum += cauchy(3,1)
        count += 1
        yield sum/count
    

Or, given a generator for Cauchy numbers and a utility function for a running
sum generator, you can have a neat generator expression:

    
    
    # Cauchy numbers generator
    def cauchy_numbers():
      while True:
        yield cauchy(3,1)
    
    # running sum utility function
    def running_sum(iterable):
      sum = 0
      for x in iterable:
        sum += x
        yield sum
    
    # Running averages generator expression (** the neat part **)
    running_avgs = (sum/(i+1) for (i,sum) in enumerate(running_sum(cauchy_numbers())))
    
    # goes on forever
    for avg in running_avgs:
      print avg
    
    # alternatively, take just the first 10
    import itertools
    for avg in itertools.islice(running_avgs, 10):
      print avg
    

