Python按名称分组Namedtuple写入CSV遇NameError问题求助
Let's break down your problem first: The NameError is happening because you're trying to use variables like Cat, Name, and Team in your dictionary d, but those variables don't exist in that scope. These values should come from the grouped namedtuples—since you're grouping by Name, all entries in a single group should share the same Cat, Name, and Team values, so you can grab them from the first element in the group.
Here are the key fixes and improvements for your code:
1. Fix Syntax & Missing Input Parsing
Your original FinalOutput line had mismatched parentheses, and you were missing code to actually read the input CSV into FullIndividualResults namedtuples (a critical step to get the data ready for grouping).
2. Correctly Retrieve Grouped Values
Instead of using undefined variables, pull Cat, Name, and Team from the first entry in the group (since all entries in the group belong to the same person).
3. Ensure Required Imports
Don't forget to import the modules you need: csv, namedtuple from collections, and groupby from itertools.
Corrected Full Code
import csv from collections import namedtuple from itertools import groupby # Define the namedtuple structure fields = ("Position", "Cat", "Name", "Team", "Points") FullIndividualResults = namedtuple('FullIndividualResults', fields) # Step 1: Parse input CSV into namedtuples (missing in your original code) input_data = [] with open("Individual Series Results Cumulative.csv", 'r') as infile: reader = csv.DictReader(infile) for row in reader: # Clean up extra spaces in names and map CSV rows to the namedtuple result = FullIndividualResults( Position=row['Position'], Cat=row['Cat'], Name=row['Name'].strip(), Team=row['Team'], Points=row['Points'] ) input_data.append(result) # Sort data by Name (required for groupby to work correctly) sorted_data = sorted(input_data, key=lambda k: k.Name) # Function to write grouped data to CSV def write_data(data_in, data_out): out = [] # Group entries by Name (using a lambda directly for simplicity) for name, group in groupby(data_in, key=lambda x: x.Name): group_list = list(group) # Grab shared values from the first entry in the group first_entry = group_list[0] # Calculate total points for the group total_points = sum(int(i.Points) for i in group_list) # Build the dictionary with valid, sourced values d = { 'Cat': first_entry.Cat, 'Name': first_entry.Name, 'Team': first_entry.Team, 'Points': total_points } out.append(d) # Write to output CSV with open(data_out, 'w', newline='') as csv_file: fieldnames = ['Cat', 'Name', 'Team', 'Points'] writer = csv.DictWriter(csv_file, fieldnames=fieldnames) writer.writeheader() for row in out: writer.writerow(row) # Run the function to generate your desired output write_data(sorted_data, "individual_results_summary.csv")
Key Explanations:
- Input Parsing: The added code reads your input CSV and converts each row into a
FullIndividualResultsnamedtuple—this is essential to get the structured data needed for grouping. - Sorting for Groupby:
groupbyonly groups consecutive matching entries, so sorting byNamefirst ensures all entries for the same person are grouped together. - Eliminating NameError: By using
first_entry.Cat,first_entry.Name, etc., we pull the shared values directly from the grouped data, which fixes the undefined variable error. - Cleaning Names: The
.strip()on theNamefield removes extra spaces (like the trailing space in yourJohn Smithexample) for cleaner output.
This code will generate the exact CSV format you're expecting, with one row per unique name and summed points.
内容的提问来源于stack exchange,提问作者PythonIsBae

