Last active
March 20, 2025 16:10
-
-
Save richard-scott/b2079f5578191eaa664b55fd64651134 to your computer and use it in GitHub Desktop.
Revisions
-
richard-scott revised this gist
Mar 20, 2025 . 1 changed file with 5 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,12 +3,13 @@ def remove_keys_recursive(original, remove): if isinstance(original, dict): # Handling dictionaries filtered_dict = {} for key in sorted(original.keys()): # Sort keys alphabetically value = original[key] if key in remove: if isinstance(value, dict) and isinstance(remove[key], dict): # Recursively process nested dictionaries filtered_value = remove_keys_recursive(value, remove[key]) if filtered_value: # Keep only non-empty dictionaries filtered_dict[key] = filtered_value elif isinstance(value, list) and isinstance(remove[key], list): # Remove specific values or dictionaries from the list @@ -18,7 +19,7 @@ def remove_keys_recursive(original, remove): else: filtered_dict[key] = remove_keys_recursive(value, remove.get(key, {})) return dict(sorted(filtered_dict.items())) if filtered_dict else None # Sort final dict keys elif isinstance(original, list): # Handling lists return remove_items_from_list(original, remove) @@ -68,7 +69,7 @@ def filters(self): 'dict_recursive_remove': custom_filter } if __name__ == '__main__': # Example Dictionary with Lists original_dict = { -
richard-scott created this gist
Mar 20, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,97 @@ from ansible.errors import AnsibleFilterError def remove_keys_recursive(original, remove): if isinstance(original, dict): # Handling dictionaries filtered_dict = {} for key, value in original.items(): if key in remove: if isinstance(value, dict) and isinstance(remove[key], dict): # Recursively process nested dictionaries filtered_value = remove_keys_recursive(value, remove[key]) if filtered_value: # Keep non-empty dictionaries filtered_dict[key] = filtered_value elif isinstance(value, list) and isinstance(remove[key], list): # Remove specific values or dictionaries from the list filtered_dict[key] = remove_items_from_list(value, remove[key]) elif remove[key] is None: continue # Fully remove this key else: filtered_dict[key] = remove_keys_recursive(value, remove.get(key, {})) return filtered_dict if filtered_dict else None # Remove empty dicts elif isinstance(original, list): # Handling lists return remove_items_from_list(original, remove) return original # Return non-dict, non-list values as is def remove_items_from_list(lst, remove_list): """ Removes elements from a list, including dictionaries, based on remove_list. """ if not isinstance(remove_list, list): return lst # If remove_list isn't a list, do nothing result = [] for item in lst: if isinstance(item, dict): # Keep dictionary items that don't fully match any dictionary in remove_list if not any(is_dict_match(item, remove_item) for remove_item in remove_list): result.append(item) else: # Remove non-dict items directly if item not in remove_list: result.append(item) return result def is_dict_match(dict1, dict2): """ Checks if dict1 matches dict2 (i.e., if dict1 contains all key-value pairs in dict2). """ if not isinstance(dict1, dict) or not isinstance(dict2, dict): return False # Only compare dicts return all(k in dict1 and dict1[k] == v for k, v in dict2.items()) def custom_filter(data, remove): try: return remove_keys_recursive(data, remove) except Exception as e: raise AnsibleFilterError(f"Error in filter: {e}") class FilterModule(object): def filters(self): return { 'dict_recursive_remove': custom_filter } # The following was used to test the above code before using it as a filter in Ansible. if __name__ == '__main__': # Example Dictionary with Lists original_dict = { "a": [1, 2, 3, 4], "b": { "c": [5, 6, 7], "d": [{"e": 10, "f": 20}, {"e": 30, "f": 40}] }, "g": [100, 200, 300] } remove_dict = { "a": [2, 3], # Remove 2 and 3 from list "a" "b": { "c": [6], # Remove 6 from list "c" "d": [{"e": 10}] # Remove dicts inside list where "e" == 10 }, "g": None # Remove the entire list "g" } filtered_dict = remove_keys_recursive(original_dict, remove_dict) # Remove top-level empty dictionaries (if necessary) filtered_dict = {k: v for k, v in filtered_dict.items() if v is not None} print(filtered_dict)