How to Implement a Mock MapReduce for Word Count in Python

Simulates a MapReduce word count pipeline with mapper, shuffle, and reducer phases using Python dicts and standard library modules.

Medium Python 3.9+ Aug 9, 2026 Big data & Spark 15 views 0 copies

Python code

38 lines
Python 3.9+
from collections import defaultdict
import re

def mapper(text):
    """Split text into words and emit (word, 1) pairs."""
    words = re.findall(r'\b\w+\b', text.lower())
    return [(word, 1) for word in words]

def reducer(pairs):
    """Group word-count pairs and sum counts."""
    counts = defaultdict(int)
    for word, count in pairs:
        counts[word] += count
    return dict(counts)

def map_reduce_word_count(texts):
    """Run mock MapReduce word count over a list of text documents."""
    # MAP phase
    mapped = []
    for text in texts:
        mapped.extend(mapper(text))

    # SHUFFLE phase (group by key)
    grouped = defaultdict(list)
    for word, count in mapped:
        grouped[word].append(count)

    # REDUCE phase
    return reducer([(word, sum(counts)) for word, counts in grouped.items()])

if __name__ == "__main__":
    documents = [
        "the cat sat on the mat",
        "the dog sat on the log",
        "cat and dog"
    ]
    result = map_reduce_word_count(documents)
    print(sorted(result.items()))

Output

stdout
[('and', 1), ('cat', 2), ('dog', 2), ('log', 1), ('mat', 1), ('on', 2), ('sat', 2), ('the', 4)]

How it works

This mock demonstrates the core MapReduce phases: the mapper splits text into (word, 1) pairs, the shuffle groups pairs by key, and the reducer sums counts per word. It uses defaultdict for clean counting and grouping, mirroring how real systems like Hadoop distribute these steps. The regex \b\w+\b handles punctuation and case normalization via lower().

Common mistakes

  • Forgetting to lower-case text, causing 'The' and 'the' to count separately
  • Grouping pairs before the shuffle step, breaking the MapReduce abstraction
  • Using `dict` instead of `defaultdict` for initial counts, raising KeyError

Variations

  1. Replace regex with `text.split()` for simpler whitespace-only tokenization
  2. Yield pairs from the mapper with a generator to reduce memory for large inputs

Real-world use cases

  • Prototyping a word-frequency analytics job locally before deploying to a Spark cluster.
  • Teaching distributed computing concepts with a tiny dataset when full Hadoop is overkill.
  • Aggregating log keywords across multiple service output files in a staging pipeline.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Big data & Spark

Related tutorials and quizzes for this topic.