Python 3读取文件学生信息为字典的字典:解决数据覆盖问题
Hey there! It sounds like you're hitting a classic pitfall with mutable objects (like dictionaries) in Python—let's break down why your data is getting overwritten and fix it with a solid solution.
Common Cause of the Overwrite Problem
The most likely culprit is that you're reusing the same inner dictionary for every student. Since dictionaries are reference types in Python, when you assign this single dictionary to multiple keys in your outer dictionary, all keys end up pointing to the exact same data. So when you update it for the next student, you're overwriting the data for all previous ones too.
Here's a simplified example of what might be going wrong in your code:
# ❌ Wrong approach: Reusing the same inner dict students = {} inner_dict = {} # Only initialized ONCE # (Imagine your file parsing logic here) for student_data in parsed_students: inner_dict['name'] = student_data['name'] inner_dict['score'] = student_data['scores'] students[student_id] = inner_dict
Every time you assign inner_dict to a new student_id, you're just adding a reference to the same dictionary—so by the end, all entries in students will show the last student's data.
Correct Solution: Create a New Dictionary for Each Student
The fix is straightforward: initialize a fresh inner dictionary for every student as you parse their data. This ensures each student's information is stored in its own independent dictionary, no more overwrites!
Here's a complete, tested code example that handles your file format correctly:
def parse_student_file(file_path): students = {} # Read the entire file and split into individual elements (split by whitespace) with open(file_path, 'r') as f: all_data = f.read().split() index = 0 total_items = len(all_data) while index < total_items: # Check if we've hit a student ID (starts with 's') if all_data[index].startswith('s'): student_id = all_data[index] # ✅ Create a NEW dictionary for this student student_info = {} # Grab the student's name student_info['name'] = all_data[index + 1] # Collect all scores until we hit the next student ID or end of list scores = [] score_index = index + 2 while score_index < total_items and not all_data[score_index].startswith('s'): # Convert score string to integer scores.append(int(all_data[score_index])) score_index += 1 student_info['score'] = scores # Add the student to our outer dictionary students[student_id] = student_info # Jump to the next student ID index = score_index else: # In case of unexpected formatting, move to next item index += 1 return students # Usage example student_dict = parse_student_file('students.txt') # Print to verify for sid, info in student_dict.items(): print(f"Student ID: {sid}") print(f"Name: {info['name']}") print(f"Scores: {info['score']}\n")
Key Fixes Explained
- Fresh Dictionary per Student: By creating
student_info = {}inside the loop for each student, we ensure each entry in the outerstudentsdictionary gets its own unique data container. - Proper Data Parsing: The code correctly handles your file's format (all students in one line, each starting with an
s-prefixed ID) by scanning until the next ID to collect all scores for a student. - Clean File Handling: Uses a
withstatement to safely handle file opening/closing, which is best practice in Python.
Test with Your Sample Input
If you run this code with your sample file content, you'll get the exact nested dictionary structure you want:
{ 's11111': {'name': 'Ahmed', 'score': [20, 18, 15, 20, 20, 18]}, 's55555': {'name': 'Suaad', 'score': [20, 20, 18, 18, 15, 16, 16, 19]}, 's33333': {'name': 'Jihad', 'score': [15, 14, 16]}, 's22222': {'name': 'Jassim', 'score': [20, 19, 20, 18, 17, 18, 20, 20, 19, 19]}, 's77777': {'name': 'Badria', 'score': [20, 18, 20, 18, 20, 18, 20, 18, 19]} }
内容的提问来源于stack exchange,提问作者Aya

