I'm working on assigning groups in Python using rules.
You could think about it like building a season for a three player based game.
Each player needs to face the other players on the list exactly once.
So suppose I have this list:
players = ['a','b','c','d','e','f','g','h','i','j','k']
Here's the expected output if we start with 'a':
game schedule for a:
game 1 = a, b, c
game 2 = a, d, e
game 3 = a, f, g
game 4 = a, h, i
game 5 = a, j, k
I'll need a schedule like that above for each player.
What I've got right now gets me 45 combinations for player 'a'... trying to figure out how to whittle it down:
players = ['a','b','c','d','e','f','g','h','i','j','k']
from itertools import combinations
num = 3
all_games = list(combinations(players, num))
a_s = []
for i in all_games:
if 'a' in i:
a_s.append(i)
I'm just not sure how to build in the condition I want.
I suppose I could (in pseudo code):
create a list without the player I want:
player = ['a']
opponents = ['b','c','d','e','f','g','h','i','j','k']
extract/get every 2 elements from the list
add player a to the extracted opponent pairs
But I don't know if that's close to the best way to solve this.
-
2Can you provide an example of what you want your output would look like? I am not sure I understand what you are askingiBeMeltin– iBeMeltin2025年09月02日 17:18:49 +00:00Commented Sep 2, 2025 at 17:18
-
@iBeMeltin yes, there's an output in there. If you think of the elements in the list as players/teams that need to be scheduled: 'a' needs to face 'b' and 'c', etc. I'm expecting to be able to give 'a' a schedule of 5 games: game 1 = a, b, c game 2 = a, d, e game 3 = a, f, g game 4 = a, h, i game 5 = a, j, k I can't schedule this game: (a, b, e) because 'a' has already been scheduled against 'b' in game 1. The output could be a dictionary like 'game 1': (a,b,c) etc. Or just a list of the right tuples, or a list of lists.postcardfiction– postcardfiction2025年09月02日 17:39:40 +00:00Commented Sep 2, 2025 at 17:39
-
1Look up Steiner Triple System. There are some rules about the number of players required to ensure everyone can meet once, with some decisions to make if there players who get left out. math.stackexchange.com/questions/3238655/…Chris– Chris2025年09月02日 17:53:09 +00:00Commented Sep 2, 2025 at 17:53
-
1How is this supposed to be possible? You have 55 pairs, each game covers 3 pairs, and 55 isn't divisible by 3.Kelly Bundy– Kelly Bundy2025年09月02日 18:00:34 +00:00Commented Sep 2, 2025 at 18:00
-
@Chris Thanks! This is exactly the right direction and I have never heard of the Steiner Triple System before!postcardfiction– postcardfiction2025年09月02日 18:00:39 +00:00Commented Sep 2, 2025 at 18:00
1 Answer 1
Here is a way to solve this problem; using for loops.
players = ['a','b','c','d','e','f','g','h','i','j','k']
player_games = {}
for opponent in range(1, len(players), 2):
player_games[f"game {int((opponent + 1) / 2)}"] = ["a", players[opponent], players[opponent+1]] # Replace "a" with your criteria of finding the player
print(player_games)
Output:
{'game 1': ['a', 'b', 'c'], 'game 2': ['a', 'd', 'e'], 'game 3': ['a', 'f', 'g'], 'game 4': ['a', 'h', 'i'], 'game 5': ['a', 'j', 'k']}
This code works assuming you have an odd amount of players (even number after excluding the player.). If you just want something like [a,l] in the end, here is a tweaked version of the code:
players = ['a','b','c','d','e','f','g','h','i','j','k',"l"]
player_games = {}
for opponent in range(1, len(players), 2):
try:
player_games[f"game {int((opponent + 1) / 2)}"] = ["a", players[opponent], players[opponent+1]]
except IndexError:
player_games[f"game {int((opponent + 1) / 2)}"] = ["a", players[opponent]]
print(player_games)
we just add a try..except block to catch an IndexError which we get with the above code.
Output:
{'game 1': ['a', 'b', 'c'], 'game 2': ['a', 'd', 'e'], 'game 3': ['a', 'f', 'g'], 'game 4': ['a', 'h', 'i'], 'game 5': ['a', 'j', 'k'], 'game 6': ['a', 'l']}
Here is a short explanation for how this code works.
We use a range to include every other letter's index (skip the first one since that is the player). We then include the current index and the index after the current one in a list. For example, ['b', 'c'] and then squash an a at the front: ['a', 'b', 'c']
The key increases by one for every iteration, but we are using range with 2 step, meaning we have to divide the opponent by two to get the game number. But, since we started at 1, we also have to add one.