August 10, 2020
Dispatch Tables in Python
@anthonycorletti

Writing multiple if-else statement clauses as a switch-style case can be a hassle to maintain, especially if you're working with dynamic switches.

With no specific case or switch implementation in python's standard library, I've liked using dispatch tables.

A dispatch table can be defined as a mapping of pointers to functions.

Let's review a simple example.

A simple if-else statement set would look like the following (assuming the run_* functions are available)

class IfElse:
    def run(self, version: str, data: bytes):
        if version.startswith("alpha"):
            return run_alpha(data)
        elif version.startswith("beta"):
            return run_beta(data)
        elif version.startswith("gamma"):
            return run_gamma(data)
        elif version.startswith("delta"):
            return run_delta(data)

But with a dispatch table we can turn that into:

class DispatchTable:
    table = {
        "alpha": run_alpha,
        "beta": run_beta,
        "gamma": run_gamma,
        "delta": run_delta
    }
    def run(self, version: str, data: bytes):
        return self.table[version](data)

What's great about dispatch tables is that we have added a new element of key definition.

We can dynamically define these keys based on whatever we want and append those to the data-structure on whatever conditions and operations we need to support in our code.

In my opinion, this kind of approach is much more desirable for a couple important reasons.

The dispatch mechanism doesn’t need to know anything specific about our function handlers.

This also converts a linear time lookup to a constant time lookup. Dictionaries are hash tables in python, so the look-up process takes a constant time, while the if-elif statement set needs a linear scan across the whole set of statements (this could get problematic if you're dynamically writing statements that could span thousands of cases 🤖).