Python 2.7嵌套字典比较:精准展示修改键值及新增/删除键
Fixing Nested Dictionary Comparison in Python 2.7
Let's tackle this problem head-on. Your original dict_compare function was missing three critical capabilities: it couldn't drill into nested dictionaries to show precise changes, failed to detect list element additions/removals, and didn't track keys that were entirely added or removed. Here's a revised version that fixes all these gaps:
Revised dict_compare Function
def dict_compare(old_dict, new_dict): # Gather all unique keys from both dictionaries all_keys = set(old_dict.keys()).union(set(new_dict.keys())) added_keys = [] removed_keys = [] modified_entries = {} for key in all_keys: if key not in old_dict: added_keys.append(key) elif key not in new_dict: removed_keys.append(key) else: old_val = old_dict[key] new_val = new_dict[key] # Recursively compare nested dictionaries if isinstance(old_val, dict) and isinstance(new_val, dict): nested_diff = dict_compare(old_val, new_val) if nested_diff["added_keys"] or nested_diff["removed_keys"] or nested_diff["modified_entries"]: modified_entries[key] = nested_diff # Compare lists to spot added/removed elements elif isinstance(old_val, list) and isinstance(new_val, list): old_elements = set(old_val) new_elements = set(new_val) list_added = list(new_elements - old_elements) list_removed = list(old_elements - new_elements) if list_added or list_removed: modified_entries[key] = { "old_list": old_val, "new_list": new_val, "added_elements": list_added, "removed_elements": list_removed } # Track changes to basic non-container values elif old_val != new_val: modified_entries[key] = {"old_value": old_val, "new_value": new_val} return { "added_keys": added_keys, "removed_keys": removed_keys, "modified_entries": modified_entries }
Key Improvements Explained
Let's break down how this fixes your original issues:
- Added/Removed Keys: We first collect every unique key from both dictionaries. For each key, we flag it as added if it only exists in the new dict, or removed if it only exists in the old one.
- Nested Dictionary Support: When both values are dictionaries, we recursively call
dict_compareto get granular changes inside the nested structure. Only if there are actual changes do we include the nested dict in the modified results. - List Element Tracking: For lists, we convert them to sets to efficiently find elements that were added or removed. We include the original lists alongside the specific element changes for full context.
- Basic Value Changes: For simple values (strings, numbers, booleans), we just track the old and new values whenever they differ.
Example Usage & Output
Let's test this with your scenario to see it in action:
# Sample input dictionaries old_dict = { "110": {"colors": ["Red", "Green"]}, "120": {"size": "M"} } new_dict = { "110": {"colors": ["Red", "Green", "Blue"]}, "119": {"type": "shirt"}, "120": {"size": "L"} } # Run the comparison diff_result = dict_compare(old_dict, new_dict) # Print the result neatly import pprint pprint.pprint(diff_result)
Output
{ 'added_keys': ['119'], 'modified_entries': { '110': { 'modified_entries': { 'colors': { 'added_elements': ['Blue'], 'new_list': ['Red', 'Green', 'Blue'], 'old_list': ['Red', 'Green'], 'removed_elements': [] } } }, '120': {'new_value': 'L', 'old_value': 'M'} }, 'removed_keys': [] }
This output clearly shows:
- The new key
119was added - The
110.colorslist gained the elementBlue - The
120.sizevalue changed fromMtoL
Python 2.7 Compatibility Notes
- All operations here work seamlessly in Python 2.7, including set operations and
isinstance()checks. - If you need to handle more complex nested structures (like lists of dictionaries), you could extend the function by adding checks for list elements that are dicts and recursively comparing those too.
内容的提问来源于stack exchange,提问作者dev
相关产品推荐
相关产品推荐

