All subjects · Computer Science · WCP04 Advanced Practical Programming and Problem-solving

Functional programming: pure functions, higher-order functions and comprehensions

Edexcel IAL Computer Science · WCP04 Advanced Practical Programming and Problem-solving

Functional programming builds programs from functions that take inputs and return outputs without changing anything else. Python is not a purely functional language, but its functional tools make code shorter, safer and easier to test.

Practise this in the app: instant marking and a fix for every mistake. Free, no email needed to start.

Practise this lesson

Pure functions, immutability and side effects

members = ("Ana", "Ben")

def add_member(group, name):
    return group + (name,)          # pure: returns a new tuple, changes nothing

def square(x):
    return x * x

def apply_twice(f, x):              # higher-order: takes a function
    return f(f(x))

new_group = add_member(members, "Cy")
print(members, new_group)
print(apply_twice(square, 3), apply_twice(lambda s: s + "!", "hi"))

Output:

('Ana', 'Ben') ('Ana', 'Ben', 'Cy')
81 hi!!

map, filter, reduce and zip

map, filter and zip return lazy objects; wrap them in list() to see every value.

Comprehensions

A list comprehension builds a list in one expression: [expression for item in items if condition]. A dictionary comprehension builds a dictionary: {key: value for ... in ...}. They often replace map and filter and are usually easier to read.

from functools import reduce
nums = [3, 8, 1, 6, 5]
print(list(map(lambda n: n * 10, nums)))
print(list(filter(lambda n: n % 2 == 0, nums)))
print(reduce(lambda acc, n: acc + n, nums, 0), reduce(max, nums))
print([n * n for n in nums if n > 4])
names = ["Ana", "Ben", "Cy"]
scores = [71, 64, 88]
print({name: score for name, score in zip(names, scores) if score > 65})
print(list(zip(names, scores)))
print(sorted(zip(names, scores), key=lambda pair: pair[1], reverse=True)[0])

Output:

[30, 80, 10, 60, 50]
[8, 6]
23 8
[64, 36, 25]
{'Ana': 71, 'Cy': 88}
[('Ana', 71), ('Ben', 64), ('Cy', 88)]
('Cy', 88)

Recursion

Functional programs repeat by recursion instead of loops that update variables. Every recursive function needs a base case that stops it, and a recursive case that moves towards the base case.

def total(items):
    if not items:                     # base case
        return 0
    return items[0] + total(items[1:])

def power(base, exp):
    if exp == 0:
        return 1
    return base * power(base, exp - 1)

print(total([4, 5, 6]), power(2, 10))

Output:

15 1024

Python limits recursion depth (about 1000 calls by default), so very deep recursion raises RecursionError.

Worked example

Rewrite this loop in functional style: `result = []`, then for each word in words, if it has more than 3 letters, append it in capitals.

  1. ```python words = ["tree", "ox", "maple", "fir"] print([w.upper() for w in words if len(w) > 3]) print(list(map(str.upper, filter(lambda w: len(w) > 3, words)))) ```
  2. Output: ``` ['TREE', 'MAPLE'] ['TREE', 'MAPLE'] ```

Answer: Both versions build a new list without mutating anything; the comprehension is usually clearer.

Key idea: Pure functions: same inputs, same output, no side effects; return new values instead of mutating; functions are first-class; higher-order functions take or return functions; lambda; map, filter, reduce, zip; list and dict comprehensions; recursion with a base case.

Check yourself

  1. What does this program print? ```python print(list(map(lambda x: x + 1, [10, 20, 30]))) ```
    Show answer

    [11, 21, 31]. map applies the lambda to each item. Output: `[11, 21, 31]`

  2. What does this program print? ```python print(list(filter(lambda w: w.startswith("b"), ["bat", "cat", "bee", "ant"]))) ```
    Show answer

    ['bat', 'bee']. filter keeps the words starting with b. Output: `['bat', 'bee']`

  3. What does this program print? ```python from functools import reduce print(reduce(lambda a, b: a * b, [2, 3, 4], 1)) ```
    Show answer

    24. reduce multiplies cumulatively: 1 x 2 = 2, 2 x 3 = 6, 6 x 4 = `24`.

  4. What does this program print? ```python names = ["Zoe", "Al", "Kit"] print({n: len(n) for n in names}) ```
    Show answer

    {'Zoe': 3, 'Al': 2, 'Kit': 3}. Each name becomes a key, with its length as the value. Output: `{'Zoe': 3, 'Al': 2, 'Kit': 3}`

  5. What does this program print? ```python a = [1, 2, 3, 4] b = ["w", "x", "y"] print(list(zip(a, b))) ```
    Show answer

    [(1, 'w'), (2, 'x'), (3, 'y')]. zip pairs items and stops at the shorter sequence, so 4 has no partner. Output: `[(1, 'w'), (2, 'x'), (3, 'y')]`

  6. What does this program print? ```python def add_item(basket, item): return basket + [item] b1 = ["egg"] b2 = add_item(b1, "milk") print(b1, b2) ```
    Show answer

    ['egg'] ['egg', 'milk']. add_item is pure: `basket + [item]` builds a new list, so b1 is unchanged. Output: `['egg'] ['egg', 'milk']`

  7. What does this program print? ```python def digits(n): if n < 10: return 1 return 1 + digits(n // 10) print(digits(40517)) ```
    Show answer

    5. Each call removes the last digit until one digit is left: 40517, 4051, 405, 40, 4, giving `5`.

  8. Which function is pure?
    • `def area(w, h): return w * h`
    • `def log(x): print(x); return x`
    • `def add(lst, x): lst.append(x); return lst`
    • `def tick(): global count; count += 1; return count`
    Show answer

    `def area(w, h): return w * h`. area depends only on its arguments and changes nothing outside itself.

Practise with instant feedback

Sources

Last updated 8 November 2026. Spotted a mistake? Tell us.