Lists and Dictionaries of Functions in Python 2026
Since functions in Python are first-class objects, you can store them in lists, dictionaries, and other data structures. This powerful technique enables dynamic dispatch, plugin systems, strategy patterns, and clean command handling.
TL;DR — Key Takeaways 2026
- Store functions in lists for ordered execution or pipelines
- Use dictionaries of functions for dynamic lookup and command patterns
- This approach makes code more extensible and maintainable
- Combine with type hints for better clarity and safety
1. Lists of Functions (Pipeline Pattern)
def clean_text(text: str) -> str:
return text.strip().lower()
def remove_punctuation(text: str) -> str:
return ''.join(c for c in text if c.isalnum() or c.isspace())
def tokenize(text: str) -> list:
return text.split()
# List of processing functions (pipeline)
text_processors = [clean_text, remove_punctuation, tokenize]
def process_text(text: str):
for processor in text_processors:
if isinstance(text, str):
text = processor(text)
else:
text = processor(text) # for list output
return text
result = process_text("Hello, World! 123")
print(result) # ['hello', 'world', '123']
2. Dictionaries of Functions (Command / Strategy Pattern)
def add(a: int, b: int) -> int: return a + b
def subtract(a: int, b: int) -> int: return a - b
def multiply(a: int, b: int) -> int: return a * b
def divide(a: int, b: int) -> float:
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b
# Dictionary mapping operation names to functions
operations = {
"add": add,
"subtract": subtract,
"multiply": multiply,
"divide": divide,
}
def calculate(operation: str, a: int, b: int):
if operation not in operations:
raise ValueError(f"Unknown operation: {operation}")
func = operations[operation]
return func(a, b)
print(calculate("add", 10, 5)) # 15
print(calculate("multiply", 10, 5)) # 50
3. Best Practices in 2026
- Use lists of functions for ordered processing pipelines
- Use dictionaries for command patterns and dynamic dispatch
- Store only callable objects and validate them
- Add type hints and clear documentation for each function
- Consider using enums or constants as keys for better safety
Why Store Functions in Lists and Dictionaries
Since functions are objects, a list can hold a sequence of steps and a dictionary can map names to actions. This replaces long if/elif chains with data that is easy to extend: adding a step or a command means adding one entry.
A list of functions is a natural pipeline. Each step takes the data and returns a new version, and a loop applies them in order. Reordering or disabling a step is a one-line change.
A dictionary of functions is a dispatch table. A key such as an aggregation name or a command maps directly to the function that handles it. dict.get with a default function gives a clean answer for unknown keys.
Both patterns make testing easier, because each small function can be tested on its own.
Worked Example: A Cleaning Pipeline and a Dispatch Table
We clean a list of strings with a pipeline, then summarise numbers with a dispatch table.
import statistics
def strip_all(xs): return [x.strip() for x in xs]
def drop_empty(xs): return [x for x in xs if x]
def to_float(xs): return [float(x) for x in xs]
PIPELINE = [strip_all, drop_empty, to_float]
data = [" 4", "", "10 ", " 7 "]
for step in PIPELINE:
data = step(data)
print(data)
SUMMARY = {"mean": statistics.mean, "median": statistics.median, "max": max}
for name in ["mean", "median", "max", "mode"]:
func = SUMMARY.get(name, lambda xs: "unknown")
print(name, func(data))
The pipeline turns the messy strings into [4.0, 10.0, 7.0]. The dispatch table returns a mean of 7.0, a median of 7.0 and a max of 10.0, and the unknown key mode falls back to the default function.
Common Mistakes
- Calling the functions while building the list, storing results instead.
- Steps that modify the input in place and surprise later steps.
- Using d[key] and crashing on unknown keys.
- Hiding very different signatures behind one dispatch table.
Quick Summary
- Lists of functions form pipelines.
- Dictionaries of functions form dispatch tables.
- Use .get with a default for unknown keys.
- Keep each step small and testable.
Conclusion
Storing functions in lists and dictionaries is a powerful Python idiom that leads to cleaner, more extensible, and maintainable code. In 2026, this technique is widely used for building plugin systems, command handlers, processing pipelines, and flexible APIs.
Next steps:
- Look for opportunities in your code to replace long if-elif chains with dictionaries of functions