Python中使用yaml.dump序列化嵌套defaultdict时去除冗余内容的方法
The Problem
You've built a nested defaultdict structure to organize greenhouse data, but when serializing with yaml.dump(), you're stuck with messy Python-specific metadata you don't want:
First, your setup code (note: I fixed a small error—sets use add() instead of append()):
from collections import defaultdict import yaml db = defaultdict(lambda: defaultdict(set)) db['greenhouse1']['fruits'].add('apples') db['greenhouse1']['fruits'].add('oranges') db['greenhouse1']['colors'] = ["red", "orange"] db['greenhouse2']['fruits'].add('banana')
The unwanted YAML output:
greenhouse1: !!python/object/apply:collections.defaultdict args: - *d001 dictitems: fruits: - oranges - apples colors: - orange - red greenhouse2: !!python/object/apply:collections.defaultdict args: - *d001 dictitems: fruits: - banana
You want to strip out the args and dictitems cruft and keep only the clean hierarchical data.
The Solution
PyYAML includes that metadata because defaultdict is a custom Python type, not a native dictionary. To fix this, you need to recursively convert your nested defaultdict structure into standard Python types (dict and list—since YAML doesn't support sets natively).
Here's a reusable conversion function:
def convert_nested_defaultdict(obj): if isinstance(obj, defaultdict): # Turn defaultdict into a regular dict, then recurse on its values return {key: convert_nested_defaultdict(value) for key, value in obj.items()} elif isinstance(obj, set): # Convert sets to lists for YAML compatibility (no native set type in YAML) return list(obj) else: # Leave other types (like lists, strings) as-is return obj
Use it to clean your data before dumping to YAML:
# Convert the nested defaultdict to standard Python types clean_db = convert_nested_defaultdict(db) # Dump the cleaned data (sort_keys=False preserves your original order) print(yaml.dump(clean_db, sort_keys=False))
The Clean Result
You'll get the tidy, hierarchical output you're after:
greenhouse1: fruits: - apples - oranges colors: - red - orange greenhouse2: fruits: - banana
Why This Works
By converting defaultdict to a regular dict, you're telling PyYAML to treat the structure as a native mapping type instead of a custom Python object. This removes the need to serialize the defaultdict's constructor arguments and internal storage details. Converting sets to lists ensures compatibility with YAML's native data types, avoiding extra Python-specific tags in your output.
内容的提问来源于stack exchange,提问作者Nicholas Tripp

