Skip to Content
Course content

176: The itertools Module: combinations and permutations

Click on the "Edit" button in the top corner of the screen to edit your slide content.

A few years ago, I was helping a colleague build a small tool for a local esports league. They needed to generate a schedule for a round-robin tournament where every team played every other team exactly once. I watched them struggle for an hour writing nested for loops, trying to figure out how to avoid "Team A vs Team A" and how to prevent "Team A vs Team B" from being listed separately from "Team B vs Team A." The code was becoming a jungle of if statements and index offsets.

It's a classic trap. When we think about "every possible pair" or "every possible ordering," our instinct is to reach for nested loops. But the moment you need a group of three or four, or the moment the order of those items starts to matter, your logic collapses under its own weight. This is exactly why the itertools module exists. It handles the combinatorial math under the hood so you can focus on what to do with the results.

Generating Unique Pairings with combinations

When the order of the items doesn't matter—meaning a pair of {Alice, Bob} is the same thing as {Bob, Alice}—you want itertools.combinations. This is what my colleague needed for the tournament matchups. You provide an iterable and a length r, and Python yields every possible unique subset of that length.

from itertools import combinations

teams = ['Dragons', 'Knights', ' Wizards', 'Titans']
# We want pairs (2 teams per match)
matchups = list(combinations(teams, 2))

for match in matchups:
    print(f"{match[0]} vs {match[1]}")

Notice that we don't get "Dragons vs Dragons" and we don't get both "Dragons vs Knights" and "Knights vs Dragons." It's clean, it's efficient, and it's far more readable than a manual loop. One thing to keep in mind: combinations returns an iterator. If you need to access the results multiple times or know the total count immediately, you'll need to cast it to a list, though for large datasets, iterating over it directly is much kinder to your RAM.

Handling Sequence and Rank with permutations

Now, there are times when the order does matter. If we aren't talking about who is playing whom, but rather who wins Gold, Silver, and Bronze, then {Alice, Bob, Charlie} is a very different outcome than {Charlie, Bob, Alice}. For this, we use itertools.permutations.

Permutations generate every possible arrangement. If you have four teams and you want to see every possible way the top three spots could be filled, the number of results grows much faster than it does with combinations.

from itertools import permutations

players = ['Alice', 'Bob', 'Charlie', 'Diana']
# Top 3 finishers: Gold, Silver, Bronze
podiums = list(permutations(players, 3))

print(f"Total possible outcomes: {len(podiums)}")
# Example output: ('Alice', 'Bob', 'Charlie'), ('Alice', 'Bob', 'Diana'), etc.

I usually tell people to be careful with permutations. Because it considers order, the number of results can explode (factorial growth). If you accidentally run a permutation on a list of 20 items without a small r value, you're going to hang your program. Always double-check if the order actually changes the meaning of your data before choosing this over combinations.




📋 Practical Task

The Tournament Pairing and Podium Generator

You are tasked with creating a utility for a chess club. The club has a list of players, and they need two things: a list of all unique matches for their "Friendly Friday" round-robin and a list of all possible ways the top two players could finish (First and Second place) for their trophy ceremony.

Write a script that does the following:

  • Create a list called players containing: "Magnus", "Hikaru", "Fabiano", "Ian".
  • Use itertools.combinations to generate all unique pairings of 2 players. Print these as: "Match: [Player 1] vs [Player 2]".
  • Use itertools.permutations to generate all possible ways these players could take 1st and 2nd place. Print these as: "1st: [Player 1], 2nd: [Player 2]".
Rating
0 0

There are no comments for now.

to be the first to leave a comment.