How to Compute a Moving Average in Python

This code computes the moving average over a numeric list using an efficient sliding window sum, avoiding recomputation of each window.

Easy Python 3.9+ Aug 9, 2026 Lists & loops 15 views 0 copies

Python code

33 lines
Python 3.9+
def moving_average(data, window_size):
    """
    Compute the moving average over a numeric list.
    
    Args:
        data: List of numeric values
        window_size: Size of the sliding window (positive integer)
    
    Returns:
        List of moving averages, each representing the mean of a window
    """
    if window_size <= 0:
        raise ValueError("Window size must be positive")
    if window_size > len(data):
        return []
    
    result = []
    window_sum = sum(data[:window_size])
    result.append(window_sum / window_size)
    
    for i in range(window_size, len(data)):
        window_sum += data[i] - data[i - window_size]
        result.append(window_sum / window_size)
    
    return result

if __name__ == "__main__":
    numbers = [10, 20, 30, 40, 50, 60]
    window = 3
    averages = moving_average(numbers, window)
    print(f"Data: {numbers}")
    print(f"Window size: {window}")
    print(f"Moving averages: {averages}")

Output

stdout
Data: [10, 20, 30, 40, 50, 60]
Window size: 3
Moving averages: [20.0, 30.0, 40.0, 50.0]

How it works

The function initializes the sum of the first window using sum(data[:window_size]). For each subsequent window, it updates the sum by adding the next element and subtracting the first element of the previous window, achieving O(n) time complexity. The result list stores each average computed as window_sum / window_size. This sliding window technique is efficient for large datasets because it reuses the previous sum instead of recalculating from scratch.

Common mistakes

  • Modifying the original data list inside the function, which can affect calling code
  • Forgetting to handle edge cases like empty data or window size larger than the list
  • Using integer division `/` correctly for floats, but forgetting to convert data to float if needed
  • Not raising an error or returning empty list for invalid window sizes

Variations

  1. Use `statistics.mean` on a slice inside a list comprehension with a `range` loop for readability (but slower).
  2. Use `collections.deque` with `maxlen=window_size` to maintain the window for streaming data.

Real-world use cases

  • Smoothing time-series sensor data to remove short-term fluctuations before plotting.
  • Computing a rolling revenue average over the last 7 days for a business dashboard.
  • Reducing noise in financial stock prices before feeding into a trading algorithm.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Lists & loops

Related tutorials and quizzes for this topic.