Python函数highest_n_scores优化及测试异常问询
Hey there! Let's tackle your two questions clearly and directly:
1. Why your self-test works but the tester marks it wrong?
The core issue is hardcoding player names in your implementation. Your code only handles bill, jack, sheldon, tina, amy, and bob—but the problem statement explicitly requires you to process all players present in the input scores list.
The tester’s test cases likely include scenarios your code can’t handle:
- A player not in your hardcoded list (like
alice), which your code will completely ignore, violating the requirement to return results for every input player. - A missing hardcoded player (e.g., no
bobin the input), where your code still includes them in the result with a total score of 0—this is incorrect per the problem rules.
Your self-test uses exactly those 6 players, so it works—but the tester uses cases that don’t match this fixed set, hence the failure.
2. A more efficient, scalable implementation
Instead of hardcoding names, use a dictionary to group scores by player dynamically. This approach is flexible, maintainable, and works for any set of players in the input. Here’s a clean, correct implementation:
from collections import defaultdict def highest_n_scores(scores, n=5): # Group all scores by player name dynamically player_scores = defaultdict(list) for name, score in scores: player_scores[name].append(score) # Calculate total for each player and sort results alphabetically return sorted( (name, sum(sorted(scores_list)[-n:])) for name, scores_list in player_scores.items() )
Key improvements:
- Dynamic player handling: Automatically processes every player in the input, no matter how many there are.
- Correctness: For players with fewer than
nscores,sorted(scores_list)[-n:]safely returns all their scores (Python slicing doesn’t throw errors for out-of-bounds indices), which aligns perfectly with the requirement. - Conciseness: Uses generator expressions and built-in functions to eliminate redundant, repetitive code.
- Efficiency: Time complexity matches your original code (O(m log m) where m is the total number of scores), but it’s far more scalable and less error-prone.
If you prefer not to use defaultdict, you can use a regular dictionary with dict.setdefault:
def highest_n_scores(scores, n=5): player_scores = {} for name, score in scores: player_scores.setdefault(name, []).append(score) return sorted( (name, sum(sorted(scores_list)[-n:])) for name, scores_list in player_scores.items() )
Both versions will correctly handle all edge cases the tester throws at you.
内容的提问来源于stack exchange,提问作者Syed Allay Ali

