PythonMastery
Python programs · Strings · intermediate

Compress repeated characters in a string in Python

Replace each run of the same character with the character and its count, so aaabbbcc becomes a3b3c2. With a loop, and with itertools.groupby().

This is called run-length encoding. Each run (the same character repeated next to itself) is written once, followed by how many times it repeats. A character that appears only once is written without a number.

The program

python
def compress(text):
    if text == "":
        return ""

    result = ""
    current = text[0]
    count = 1

    for ch in text[1:]:
        if ch == current:
            count += 1
        else:
            result += current + (str(count) if count > 1 else "")
            current = ch
            count = 1

    # the last run has no different character after it, so add it here
    result += current + (str(count) if count > 1 else "")
    return result


for word in ["aaabbbcc", "aabcccccaaa", "abc", "z", ""]:
    print(f"{word!r} -> {compress(word)!r}")
output
'aaabbbcc' -> 'a3b3c2'
'aabcccccaaa' -> 'a2bc5a3'
'abc' -> 'abc'
'z' -> 'z'
'' -> ''

How it works

Another way: itertools.groupby()

groupby() from the itertools module splits a string into runs for you. For each run it gives the character and the group of repeated characters:

python
from itertools import groupby

def compress(text):
    result = ""
    for ch, group in groupby(text):
        count = len(list(group))
        result += ch + (str(count) if count > 1 else "")
    return result


print(compress("aabcccccaaa"))
output
a2bc5a3

Note that "aaa" at the end is a separate run from "aa" at the start. Runs are counted only when the same characters are next to each other.

Learn the idea: Working with Strings, Loops: for, while, and the Pythonic Patterns, Itertools: Composable Iterator Building Blocks