如何在Python中按类别将元组列表分组为字典?itemgetter使用问题排查与解决
Let's start by breaking down what's wrong with your current code, then walk through working solutions that hit your goal perfectly.
What's Wrong with Your Current Code?
Your attempt has a few critical issues that keep it from working:
- Syntax Error: The line
sorted(words, key = itemgetter category: category['food', 'animal', 'job'])is completely invalid.itemgettertakes an index or key (likeitemgetter(0)to grab the first element of each tuple), not that custom category syntax you used. - No Grouping Logic:
sorted()only rearranges the list—it doesn't actually group items by category. You also didn't assign the sorted result to a variable, so that line does nothing useful. - No Return Value: Your function doesn't return anything, so calling
create_dict(words)will just giveNoneinstead of your target dictionary. - No Duplicate Handling: You didn't add logic to store words as unique sets (which is necessary for duplicates like
('job', 'gardener')in your input list).
Correct Implementations
Option 1: Using collections.defaultdict (Simple & Efficient)
This is the most straightforward approach—no sorting required, and it naturally handles grouping and duplicate removal with sets:
from collections import defaultdict def create_dict(words): # Initialize a dictionary where each key maps to an empty set category_map = defaultdict(set) # Iterate over each (category, word) tuple for category, word in words: # Add the word to the category's set (automatically ignores duplicates) category_map[category].add(word) # Convert to a regular dictionary (optional, but matches your expected output type) return dict(category_map)
Option 2: Using itertools.groupby (Matches Your itemgetter Idea)
If you want to use itemgetter as you initially tried, groupby works—but remember it requires the list to be sorted by the grouping key first (since it only groups consecutive matching items):
from operator import itemgetter from itertools import groupby def create_dict(words): # Sort the list by category (first element of each tuple) using itemgetter sorted_words = sorted(words, key=itemgetter(0)) category_map = {} # Group the sorted list by category for category, group in groupby(sorted_words, key=itemgetter(0)): # Extract all words from the group and convert to a set to remove duplicates category_map[category] = {word for _, word in group} return category_map
Testing the Code
When you run either function with your words list, you'll get the expected result (note: your sample expected result has a trailing space in 'food '—that's likely a typo; the correct keys are 'food', 'animal', and 'job'):
words = [('food', 'apple'), ('food', 'almond'), ('food', 'apricot'), ('food', 'beancurd'), ('food', 'bacon'),('food', 'bread'), ('food', 'beans'), ('food', 'broccoli'), ('food', 'cake'), ('food', 'chili'), ('animal', 'ape'), ('animal', 'ant'), ('animal', 'bat'), ('animal', 'bear'), ('animal', 'cat'),('animal', 'dog'), ('animal', 'flea'), ('animal', 'horse'), ('animal', 'lamb'), ('animal', 'leopard'),('job', 'baker'), ('job', 'farmer'), ('job', 'builder'), ('job', 'teacher'), ('job', 'pilot'), ('job', 'gardener'), ('job', 'gardener'), ('job', 'secretary'), ('job', 'salesman'), ('job', 'programmer'), ('job', 'manager')] print(create_dict(words)) # Output matches your expected dictionary (with correct keys and unique word sets)
内容的提问来源于stack exchange,提问作者Edwin Eng

