如何修改JSON嵌套object/array的所有值并保留原有结构?
保留JSON嵌套结构的字段匿名化实现
问题描述
现有如下JSON数据:
json_string = '[ { "degree": "masters", "school": "PU", "joinedOn": { "year": 2021, "month": "FEB" }, "address": [ { "b_Address": "UK", "city": "London" }, { "b_Address": "US", "city": "Texas" } ], "fieldOfStudy": "MBA", "levelOfEducation": "MASTER", "currentlyStudying": "true" } ]'
需要对指定字段(degree、school、joinedOn、address等)进行匿名化,但保留原有嵌套结构:
- 替换
joinedOn对象内的year、month为随机值 - 替换
address数组中每个对象的b_Address、city为随机值
当前代码会直接将嵌套对象/数组替换为单一随机字符串,破坏原有结构,需要调整实现逻辑。
现有代码片段:
import json import string import random def load_json_data(json_string): try: data = json.loads(json_string) return data except json.JSONDecodeError as e: print("Error parsing JSON:", str(e)) return None def anonymize_json_data(data, fields_to_anonymize): for field in fields_to_anonymize: if field in data: data[field] = generate_random_string() return data def generate_random_string(length=8): letters_and_digits = string.ascii_letters + string.digits return ''.join(random.choice(letters_and_digits) for _ in range(length)) # 执行代码 json_string = '[{"degree": "masters", "school": "PU", "joinedOn": {"year": 2021, "month": "FEB"}, "address": [{"b_Address": "UK", "city": "London"},{"b_Address": "US", "city": "Texas"}], "fieldOfStudy": "MBA","levelOfEducation": "MASTER","currentlyStudying": "true"}]' data = load_json_data(json_string) if data: fields_to_anonymize = ["degree", "school","phone","joinedOn","address"] anonymized_data = anonymize_json_data(data[0], fields_to_anonymize) anonymized_json_string = json.dumps(anonymized_data) print(anonymized_json_string)
解决方案
核心思路是递归遍历JSON结构,针对不同数据类型(字典、列表、基础类型)做差异化处理:
- 若当前是字典:遍历所有键,若键在待匿名化列表中,则递归处理对应的值;否则跳过
- 若当前是列表:遍历列表中的每个元素,递归处理每个元素
- 若当前是基础类型(字符串、数字等):替换为对应类型的随机值
修改后的完整代码:
import json import string import random from typing import Any def load_json_data(json_string): try: data = json.loads(json_string) return data except json.JSONDecodeError as e: print("Error parsing JSON:", str(e)) return None def generate_random_value(value: Any) -> Any: """根据输入值的类型生成对应随机值""" if isinstance(value, int): # 针对年份生成1990-2025之间的随机整数 return random.randint(1990, 2025) elif isinstance(value, str): # 生成8位随机字符串 letters_and_digits = string.ascii_letters + string.digits return ''.join(random.choice(letters_and_digits) for _ in range(8)) # 可扩展其他类型(如布尔值等) return value def anonymize_field(value: Any) -> Any: """递归处理单个字段的值,保留结构替换内容""" if isinstance(value, dict): # 遍历字典的每个键值对,递归处理值 return {k: anonymize_field(v) for k, v in value.items()} elif isinstance(value, list): # 遍历列表每个元素,递归处理 return [anonymize_field(item) for item in value] else: # 基础类型,生成随机值替换 return generate_random_value(value) def anonymize_json_data(data: dict, fields_to_anonymize: list) -> dict: """处理整个JSON对象,仅匿名化指定字段""" for field in fields_to_anonymize: if field in data: data[field] = anonymize_field(data[field]) return data # 执行示例 if __name__ == "__main__": json_string = '[{"degree": "masters", "school": "PU", "joinedOn": {"year": 2021, "month": "FEB"}, "address": [{"b_Address": "UK", "city": "London"},{"b_Address": "US", "city": "Texas"}], "fieldOfStudy": "MBA","levelOfEducation": "MASTER","currentlyStudying": "true"}]' data = load_json_data(json_string) if data: fields_to_anonymize = ["degree", "school", "joinedOn", "address"] anonymized_data = anonymize_json_data(data[0], fields_to_anonymize) print(json.dumps(anonymized_data, indent=2))
代码说明
generate_random_value:根据输入值的类型生成匹配的随机值,比如给整数类型(如year)生成随机年份,给字符串类型生成随机字符串,可按需扩展布尔值、浮点数等其他类型的处理逻辑anonymize_field:递归遍历嵌套结构,字典和列表会被逐层拆解处理内部元素,确保结构完全保留anonymize_json_data:仅针对指定字段触发匿名化逻辑,未列入的字段保持原内容不变
运行后输出示例(随机值每次不同):
{ "degree": "xQ7ZkL2P", "school": "m9BvT5sR", "joinedOn": { "year": 2008, "month": "aD3FgH7J" }, "address": [ { "b_Address": "kL9PqR2S", "city": "tU4VwX6Y" }, { "b_Address": "zA1BcD3E", "city": "fG5HiJ7K" } ], "fieldOfStudy": "MBA", "levelOfEducation": "MASTER", "currentlyStudying": "true" }
内容的提问来源于stack exchange,提问作者AB21
相关产品推荐
相关产品推荐

