如何在Python中对比两个列表并生成字典,计算每人平均成绩?
How to Calculate Average Grades by Name from Two Lists
Let's walk through fixing this problem step by step. Your current code has a couple of key issues (like the incorrect if name == names check, and not pairing names with their corresponding grades) so we'll address those first, then build a clean solution.
The Core Problem
We need to:
- Pair each name in
nameswith its matching grade ingrades(noting thatgradesis longer, so we only use the firstlen(names)entries) - Track the total score and number of occurrences for each name
- Calculate the average by dividing total score by occurrence count
Solution 1: Basic Dictionary Implementation
This is a straightforward approach that uses a regular dictionary to track totals and counts:
def average_grades(names, grades): # Initialize a dictionary to store total scores and counts for each name grade_tracker = {} # Truncate grades to match the length of names (since grades is longer) matched_grades = grades[:len(names)] # Iterate over paired names and grades for name, grade in zip(names, matched_grades): if name in grade_tracker: # If the name exists, add to total score and increment count grade_tracker[name]["total"] += grade grade_tracker[name]["count"] += 1 else: # If it's the first time seeing the name, initialize the entry grade_tracker[name] = {"total": grade, "count": 1} # Convert the tracker into a dictionary of averages return {name: data["total"] / data["count"] for name, data in grade_tracker.items()} # Test with your sample data names = ['Mary', 'Jack', 'Rose', 'Mary', 'Carl', 'Fred', 'Meg', 'Phil', 'Carl', 'Jack', 'Fred', 'Mary', 'Phil', 'Jack', 'Mary', 'Fred', 'Meg'] grades = [80, 88, 53, 80, 64, 61, 75, 80, 91, 82, 68, 76, 95, 58, 89, 51, 81, 78] print(average_grades(names, grades))
Solution 2: Simplified with collections.defaultdict
For cleaner code, we can use defaultdict from the collections module to avoid checking if a name exists in the dictionary:
from collections import defaultdict def average_grades(names, grades): totals = defaultdict(int) counts = defaultdict(int) matched_grades = grades[:len(names)] for name, grade in zip(names, matched_grades): totals[name] += grade counts[name] += 1 return {name: totals[name] / counts[name] for name in counts}
Solution 3: Using collections.Counter for Occurrences
If you prefer, we can use Counter to get the occurrence count of each name, then calculate totals separately:
from collections import Counter, defaultdict def average_grades(names, grades): name_counts = Counter(names) totals = defaultdict(int) matched_grades = grades[:len(names)] for name, grade in zip(names, matched_grades): totals[name] += grade return {name: totals[name] / name_counts[name] for name in name_counts}
Key Fixes from Your Original Code
- Replaced the invalid
if name == namescheck with proper dictionary existence checks - Paired each name with its corresponding grade using
zip()(after truncatinggradesto matchnameslength) - Added tracking for total scores and occurrence counts to calculate averages correctly
内容的提问来源于stack exchange,提问作者Ethan Chung
相关产品推荐
相关产品推荐

