Python联赛排名表实现:TestDome相关技术问题咨询
Let's break down how to implement the LeagueTable class that tracks player scores and calculates rankings based on the given rules. Since the third rule was cut off, I'll use the standard tiebreaker from the official TestDome version: if two players have the same score and number of games played, the player who appeared first in the league gets the higher rank.
Core Requirements Recap
The ranking rules are:
- Higher score = higher rank (top rank is 1)
- Same score? Player with fewer games played gets the higher rank
- Same score AND same number of games? Player who was added first to the league gets the higher rank
Implementation Code
class LeagueTable: def __init__(self): # Store player data: key = player name, value = (score, games_played) self.player_stats = {} # Maintain the order players first appeared (for tiebreaker rule 3) self.player_order = [] def record_result(self, player_name, points): # If player is new, initialize their stats and add to order list if player_name not in self.player_stats: self.player_stats[player_name] = [0, 0] # [score, games_played] self.player_order.append(player_name) # Update their score and game count self.player_stats[player_name][0] += points self.player_stats[player_name][1] += 1 def rank(self, player_name): # Create a list of tuples to sort players by the ranking rules # Sort key: (-score, games_played, index_in_order) # Negative score so higher scores come first # Lower games_played comes first # Earlier index in player_order comes first sorted_players = sorted( self.player_order, key=lambda name: (-self.player_stats[name][0], self.player_stats[name][1], self.player_order.index(name)) ) # Rank is 1-based index of the player in the sorted list return sorted_players.index(player_name) + 1
How It Works
Let's walk through the key parts:
__init__method: We use two data structures:player_stats: A dictionary to keep track of each player's total score and number of games played.player_order: A list to preserve the order players first joined the league—this is critical for the third tiebreaker.
record_resultmethod: Checks if the player is new; if so, initializes their stats and adds them to the order list. Then updates their score and game count regardless of whether they're new or existing.rankmethod: Sorts the players using a custom key that enforces all three ranking rules:-self.player_stats[name][0]: Negative score ensures higher scores are sorted first.self.player_stats[name][1]: Lower game counts come next in the sort order.self.player_order.index(name): Earlier entries in the order list have lower indices, so they get sorted first when scores and game counts are tied.
Finally, we return the 1-based rank by finding the player's position in the sorted list.
Test Cases
Let's verify the code with some examples:
Test 1: Basic Score Ranking
table = LeagueTable() table.record_result("Alice", 5) table.record_result("Bob", 3) table.record_result("Alice", 2) print(table.rank("Alice")) # Output: 1 (7 points, 2 games) print(table.rank("Bob")) # Output: 2 (3 points, 1 game)
Test 2: Tiebreaker Rule 2 (Same Score, Different Game Counts)
table = LeagueTable() table.record_result("Alice", 3) table.record_result("Bob", 3) table.record_result("Alice", 0) print(table.rank("Bob")) # Output: 1 (3 points, 1 game) print(table.rank("Alice")) # Output: 2 (3 points, 2 games)
Test 3: Tiebreaker Rule 3 (Same Score + Game Count)
table = LeagueTable() table.record_result("Alice", 3) table.record_result("Bob", 3) table.record_result("Alice", 0) table.record_result("Bob", 0) print(table.rank("Alice")) # Output: 1 (3 points, 2 games, joined first) print(table.rank("Bob")) # Output: 2 (3 points, 2 games, joined later)
If your third tiebreaker rule is different (e.g., alphabetical order of names), you can adjust the sort key accordingly—just replace self.player_order.index(name) with name for alphabetical sorting.
内容的提问来源于stack exchange,提问作者user9369933

