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.
Pure functions, immutability and side effects
- A pure function always returns the same output for the same inputs and has no side effects: it does not change its arguments, globals, files or the screen.
- Immutable values (int, str, tuple) cannot be changed, only replaced, so they cannot be altered by accident. Functional style returns a new value instead of modifying an old one:
group + (name,)rather thangroup.append(name). - First-class functions: a function is a value. It can be stored in a variable, put in a list, passed as an argument or returned from another function.
- A higher-order function takes a function as an argument or returns one.
- A lambda is a small anonymous function written in one expression:
lambda x: x * x.
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(f, items)applies f to every item.filter(f, items)keeps the items for which f returns True.reduce(f, items, start)from functools combines the items into one value, two at a time.zip(a, b)pairs up items from two sequences, stopping at the shorter.
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 1024Python 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.
- ```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)))) ```
- Output: ``` ['TREE', 'MAPLE'] ['TREE', 'MAPLE'] ```
Answer: Both versions build a new list without mutating anything; the comprehension is usually clearer.
Check yourself
- 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]`
- 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']`
- 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`.
- 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}`
- 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')]`
- 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']`
- 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`.
- 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.
Sources
- Pearson Edexcel International Advanced Subsidiary/Advanced Level in Computer Science specification, Issue 1 (March 2026)
- Pearson Edexcel IAL Computer Science Unit 4 Programming Language Subset (PLS)
- Pearson Edexcel IAL Computer Science sample assessment materials (Unit 3 and Unit 4)
Last updated 8 November 2026. Spotted a mistake? Tell us.