Python获取JSON指定键的父键路径:遇'unhashable type: list'报错求助
Got it, let's work through this problem. You're trying to get the parent key path (like PROJ1/LOB1 when searching for a1) from a JSON structure where all keys inside lists are unique, but the code you found elsewhere throws an unhashable type: 'list' error. Let's break down why that happens and fix it.
Why the Error Happens
The unhashable type: 'list' error almost always means the original code tried to use a list in a context that requires hashable objects—like using it as a dictionary key or adding it to a set. Since your JSON includes lists, the original code probably didn't handle list traversal correctly, leading it to treat lists as hashable entities (which they aren't).
Solution: Recursive Traversal with List Handling
Since your lists contain unique keys, we can write a recursive function that traverses both dictionaries and lists, building the path only from dictionary keys (since lists don't contribute to the key path). Here's a working implementation:
def find_parent_key_path(data, target_key, current_path=""): # Traverse dictionaries first if isinstance(data, dict): for key, value in data.items(): # Build the new path by appending the current dictionary key updated_path = f"{current_path}/{key}" if current_path else key # If we found the target key, return its parent path (the current path before adding this key) if key == target_key: return current_path # Recursively search the value for the target key result = find_parent_key_path(value, target_key, updated_path) if result is not None: return result # Traverse lists by checking each item (lists don't add to the path) elif isinstance(data, list): for item in data: result = find_parent_key_path(item, target_key, current_path) if result is not None: return result # If target key not found in this branch return None
How to Use It
Let's test this with a sample JSON structure matching your scenario:
# Example JSON data sample_data = { "PROJ1": { "LOB1": { "a1": "sample_value", "b1": "another_value" }, "LOB2": { "a2": "third_value" } }, "PROJ2": [ {"c1": "list_value_1"}, {"a1": "list_value_2"} # Unique key in the list, as per your requirement ] } # Find parent path for "a1" parent_path = find_parent_key_path(sample_data, "a1") print(parent_path) # Output: PROJ1/LOB1
Notes
- If your target key might appear multiple times in the JSON, modify the function to collect all paths instead of returning the first one. Here's a quick adjustment:
Calling this with the sample data would returndef find_all_parent_paths(data, target_key, current_path="", paths=None): if paths is None: paths = [] if isinstance(data, dict): for key, value in data.items(): updated_path = f"{current_path}/{key}" if current_path else key if key == target_key: paths.append(current_path) find_all_parent_paths(value, target_key, updated_path, paths) elif isinstance(data, list): for item in data: find_all_parent_paths(item, target_key, current_path, paths) return paths["PROJ1/LOB1", "PROJ2"]for keya1.
Key Fixes from the Original Code
- We never treat lists as part of the key path (since they don't have named keys), so we avoid trying to hash them.
- Recursion handles nested dictionaries and lists seamlessly without relying on hashable objects for tracking paths.
内容的提问来源于stack exchange,提问作者Pasha

