如何用Python实现团队菜品随机分配及无重复受邀团队匹配逻辑
Let's break down how to add the invitation logic to your existing Python code, while making sure we meet all your requirements clearly and efficiently.
First, let's recap the core rules for invitations:
- Each team gets 2 unique invited teams
- Invited teams must not make the same dish as the current team
- No self-invites, and no duplicate invites for the same team
Step 1: Refine the Initial Meal Assignment (Optional but Robust)
Your existing code works for teams divisible by 3, but since you have 60-70 teams (some numbers won't split evenly), let's adjust the meal count to cover all teams without missing anyone:
import pandas as pd import random # Load your data data = pd.read_excel(r'C:\Peter\Programming\Projects\Cycling\participants.xlsx') teams = data.to_dict(orient='index') participants = list(teams.keys()) # Calculate meal counts (handles non-divisible team counts) total_teams = len(participants) starter_count = total_teams // 3 main_count = total_teams // 3 desert_count = total_teams - starter_count - main_count # Covers remaining teams # Create and shuffle meal assignments total_meals = ['Starter'] * starter_count + ['Main'] * main_count + ['Desert'] * desert_count random.shuffle(total_meals) draw_meal = dict(zip(participants, total_meals))
Step 2: Build the Invitation Matching Logic
The key here is to first group teams by their assigned dish—this lets us quickly pull eligible teams (those making other dishes) without looping through every team every time.
# 1. Group teams by their assigned meal for quick lookup meal_groups = { 'Starter': [], 'Main': [], 'Desert': [] } for team, meal in draw_meal.items(): meal_groups[meal].append(team) # 2. Generate invitations for each team invitation_dict = {} for current_team in participants: current_meal = draw_meal[current_team] # Get all teams that make OTHER dishes eligible_teams = [] for meal in meal_groups: if meal != current_meal: eligible_teams.extend(meal_groups[meal]) # Remove the current team from eligible list (no self-invites) eligible_teams = [team for team in eligible_teams if team != current_team] # Randomly pick 2 unique teams (sample ensures no duplicates) invited_teams = random.sample(eligible_teams, 2) invitation_dict[current_team] = invited_teams
Step 3: Combine Results and Save
Now merge the meal assignments and invitations back into your original dataset, then save to Excel for easy access:
# Merge results into the original team data for team in teams: teams[team]['Assigned Meal'] = draw_meal[team] teams[team]['Invited Teams'] = ', '.join(map(str, invitation_dict[team])) # Format as string for Excel # Convert to DataFrame and save result_df = pd.DataFrame.from_dict(teams, orient='index') result_df.to_excel(r'C:\Peter\Programming\Projects\Cycling\meal_assignments_with_invitations.xlsx', index_label='Team ID')
Key Notes on the Logic
- Grouping by Meal: This is efficient—instead of checking every team's meal each time, we pre-sort them once, which saves time especially with 60-70 teams.
random.sample(): We use this instead of tworandom.choice()calls because it guarantees we pick 2 distinct teams, fulfilling the "no overlapping invites" rule automatically.- Edge Case Handling: Since you have 60-70 teams, even the smallest eligible group will have ~40 teams, so we'll never run out of eligible teams to pick from.
内容的提问来源于stack exchange,提问作者Peter Ramstedt

