Functional Programming in Python, Part I: Sliding Windows
software
programming
functional-programming
Author
Weyland Joyner
Published
April 8, 2026
Introduction
The default way of writing Python in the wild, particularly for data structures and algorithms style problems, involves starting with loops and conditionally updating one or more independent state variables based on multi-line control flow.
By ‘functional-lite’ I don’t mean you need to learn Haskell (though maybe we all should). In the following examples I’ll show ways of thinking about your Python programs in terms of transformations on data.
In many languages, basic FP means using map/filter/reduce in place of iterators and for loops. In Python the situation is a bit different because we have listcomps, which are very powerful and intuitive once you get used to them.
Ideally each line of your program is a self-contained declaration of a transformation on data that gets you closer to a useful output. I find this much easier to reason about and generalize than dealing with mutable state variables across many lines and for/while loops.
Fixed-Length Sliding Windows
Maximum Sum of Subarrays
Given an array of integers nums and an integer k, find the maximum sum of any contiguous subarray of size k.
Ex.
nums = [2, 1, 5, 1, 3, 2]k =3
First up we have a “naive” approach using listcomps and a helper function for readability:
def maximum_sum_of_subarrays(nums: list[int], k: int) ->int:def windows(nums: list[int], k: int) ->list[list[int]]:return [nums[i:i+k] for i inrange(len(nums) - k +1)] sums = [sum(w) for w in windows(nums, k)]returnmax(sums)nums = [2, 1, 5, 1, 3, 2]k =3print(maximum_sum_of_subarrays(nums, k))
9
One thing to note is that the number of subarrays of length k in a list nums of length n is always going to equal len(nums) - k + 1. Once you know that the solution above reads nicely but it’s suboptimal. We could express it even more concisely:
returnmax(sum(w) for w in (nums[i:i+k] for i inrange(len(nums) - k +1)))
But the problem is sum(w) rescans each window. So, it’s O(n*k). But look how closely it mirrors the problem statement:
find the maximum sum of any contiguous subarray of size k
max(sum(w) for w in windows(nums, k))
Alright, the solution to the compute complexity is using prefix sums.
from itertools import accumulatedef maximum_sum_of_subarrays_v2(nums: list[int], k: int) ->int:"""Use prefix sums """ prefix = [0] +list(accumulate(nums))# [2, 3, 8, 9, 12, 14]# accumulate is a scan (similar to Haskell's scanl)# that sums = [prefix[i+k] - prefix[i] for i inrange(len(nums) - k +1)]returnmax(sums)
OK now let’s do one with a condition - the subarray cannot include any duplicate values.
def maximum_unique_sum_of_subarrays(nums: list[int], k: int) ->int:def windows(nums: list[int], k: int) ->list[list[int]]:return (nums[i:i+k] for i inrange(len(nums) - k +1))def is_unique(window: list[int]) ->bool:returnlen(set(window)) ==len(window)returnmax(sum(w) for w in windows(nums, k) if is_unique(w))
Given an array of integers representing card values, write a function to calculate the maximum score you can achieve by picking exactly k cards.
You must pick cards in order from either end. You can take some cards from the beginning, then switch to taking cards from the end, but you cannot skip cards or pick from the middle.