Moving actions out of the loop
Since picking team captains only happens once per program run, there's no need to have it inside the main loop. I'll use the get_captain() function and the TEAM_SIZE constant from @toolic's answer.
team_1.append(get_captain(1))
team_2.append(get_captain(2))
while len(team_1) < TEAM_SIZE and len(team_2) < TEAM_SIZE:
# Team 1 selection
if len(team_1) < TEAM_SIZE:
pick = random.choice(available_players)
team_1.append(pick)
available_players.remove(pick)
# Team 2 selection
if len(team_2) < TEAM_SIZE:
pick = random.choice(available_players)
team_2.append(pick)
available_players.remove(pick)
Notice that we no longer need to check if team_1: and if team_2: because these are always true.
Furthermore, the remaining if conditions here are redundant due to the while condition, so we can delete those, too.
team_1.append(get_captain(1))
team_2.append(get_captain(2))
while len(team_1) < TEAM_SIZE and len(team_2) < TEAM_SIZE:
# Team 1 selection
pick = random.choice(available_players)
team_1.append(pick)
available_players.remove(pick)
# Team 2 selection
pick = random.choice(available_players)
team_2.append(pick)
available_players.remove(pick)
Separating actions
Picking players for both teams in a single loop is part of why there is so much code duplication. It doesn't matter if players are picked for each team in turns or if team 1 picks seven random players all at once. Let's see what happens when we pick teams in two loops.
while len(team_1) < TEAM_SIZE:
pick = random.choice(available_players)
team_1.append(pick)
available_players.remove(pick)
while len(team_2) < TEAM_SIZE:
pick = random.choice(available_players)
team_2.append(pick)
available_players.remove(pick)
But, because there are 14 players in the available players list, all of the remaining players will be put on team 2. So the second loop can be replaced with team_2.extend(available_players).
while len(team_1) < TEAM_SIZE:
pick = random.choice(available_players)
team_1.append(pick)
available_players.remove(pick)
team_2.extend(available_players)
Replacing loops
Starting here, I'm going to be introducing new functions that can replace loops.
Is there a different way to create team 1 without a loop? There is a random function called sample() that can make multiple random choices without duplicates. So, team 1 can be created by
team_1.extend(random.sample(available_players, TEAM_SIZE - 1))
Now we have a problem forming team 2 since the players on team 1 were not removed from the available players. One way to fix this is to remove them directly.
team_1.extend(random.sample(available_players, TEAM_SIZE - 1))
for player in team_1[1:]: # Skipping the captain
available_players.remove(player)
team_2.extend(available_players)
To do this with less work, we can use the set container. These can do a lot of work easily and efficiently when we want to add or remove items from collections. In this case, we create a set from the available players, and then subtract the team 1 players to arrive at team 2.
team_2.extend(set(available_players) - set(team_1))
Putting everything together
For the final program, I initialized both team lists with their captains.
import random
def get_captain(team):
"""
Ask user to input a team captain name for a specified team number.
Input: team is an integer
Returns a string
"""
captain = input(f"Hello Team {team}\nChoose your captain: ")
while captain == "":
captain = input(f"Team {team} Captain Needed!: ")
return captain
# List of all available players
available_players = [
"Anastasia", "Eli", "Jamal", "Jada", "Theo", "Michelle", "Adam",
"Rhea", "Charlie", "Jasmine", "Marley", "Kenji", "Sydney", "Yara"
]
TEAM_SIZE = 8
# Lists to store team members
team_1 = [get_captain(1)]
team_2 = [get_captain(2)]
team_1.extend(random.sample(available_players, TEAM_SIZE - 1))
team_2.extend(set(available_players) - set(team_1))
# Game starts when both teams are full
print("All Teams Full:")
print("Team 1:", team_1)
print("Team 2:", team_2)
print("\nIt's Game Time!!")