多级字典嵌套解析合并,两嵌套字典对不返不同
1.字典解析与合并
class ConfigConverter: """ get source translate data, merge translate data and source data """ translate_v = ["value"] translate_n = ["name"] translate_v_and_sub = [ "value", ("sub_list", ["value"]), ] translate_n_category = ["name", "category_value"] translate_v_category = ["value", "category_value"] translate_country_lists = [ "value", ("region_lists", ["display_name", ("location_lists", ["value"])]), ] translate_address_lists = [ "name", ("countrys", ["name", ("regions", ["name"])]), ] translate_location_lists = [ "value", "display_name", ("locations", ["value", "region_display_name"]), ] translate_title_description_category = ["title", "description", "category_value"] translate_title_description = ["title", "description"] translate_title = ["title"] translate_main_job_function_lists = [ "value", ( "sub_function_list", [ "value", ("job_titles", ["value"]), ("skills", ["value"]), ], ), ] translate_v_permissions = ["value", ("permissions", ["value"])] def __init__(self): self.translate_maps = { "xp_lvls": self.translate_v, "job_types": self.translate_v, "degrees": self.translate_v, "no_of_employee_ranges": self.translate_v, "company_sizes": self.translate_v, "industry_lists": self.translate_v, "job_category_lists": self.translate_v_and_sub, "job_benefit_lists": self.translate_n_category, "job_attractive_reasons": self.translate_v, "company_benefit_lists": self.translate_v_category, "company_culture_lists": self.translate_v_category, "company_financing_stage_lists": self.translate_v, "country_lists": self.translate_country_lists, "address_lists": self.translate_address_lists, "location_lists": self.translate_location_lists, "chat_report_lists": self.translate_v, "notice_period_lists": self.translate_v, "subscibe_job_frequency_lists": self.translate_v, "report_job_reasons": self.translate_title_description_category, "report_talent_reasons": self.translate_title_description, "gender_lists": self.translate_v, "pipeline_stage_lists": self.translate_v, "resume_last_updated_time_lists": self.translate_v, "main_job_function_lists": self.translate_main_job_function_lists, "report_interview_reasons": self.translate_title_description, "report_recruiter_reasons": self.translate_title_description, "report_company_reasons": self.translate_title_description, "work_xps": self.translate_v, # "educations": self.translate_v, "salary_range_filters": self.translate_v, "users": self.translate_v, "jobs": self.translate_v, # "company_documents": self.translate_v, "recruiter_documents": self.translate_v, "job_seeker_work_xps": self.translate_v, "job_seeker_prefs": self.translate_v, "job_seeker_edus": self.translate_v, "saved_jobs": self.translate_v, "saved_candidates": self.translate_v, "blacklisted_users": self.translate_v, "blacklisted_companies": self.translate_v, "job_seeker_resumes": self.translate_v, "job_applications": self.translate_v, "dialogues": self.translate_v, # "chats": self.translate_v, "interview_result": self.translate_v, "recruiter_role_permissions": self.translate_v_permissions, # "feature_banners": self.translate_title, "recruiter_chat_type_filters": self.translate_v, "recruiter_chat_status_filters": self.translate_v, "jobseeker_chat_type_filters": self.translate_v, "company_types": self.translate_v, "recruiter_badge_types": self.translate_n, "recruiter_badge_tiers": self.translate_n, } def gen_translate_data( self, source_data, translate_map, translate_data, current_key ): for _, item in enumerate(source_data): for map_key in translate_map: if isinstance(map_key, str): key = ".".join([current_key, str(item["id"]), map_key]) translate_data[key] = item[map_key] elif isinstance(map_key, tuple): v_key = map_key[0] key = ".".join([current_key, str(item["id"]), map_key[0]]) value = item[v_key] new_map_key = map_key[1] self.gen_translate_data(value, new_map_key, translate_data, key) def gen_translate_key_values(self, source_data, translate_data, current_key=""): for key, value in source_data.items(): if key in self.translate_maps and isinstance(value, list): if current_key: key = ".".join([current_key, key]) if key.startswith("country_diff"): translate_map = self.translate_maps[key.split(".")[-1]] else: translate_map = self.translate_maps[key] self.gen_translate_data(value, translate_map, translate_data, key) elif isinstance(value, dict): if current_key: key = ".".join([current_key, key]) self.gen_translate_key_values(value, translate_data, key) return translate_data def merge_translate_data( self, source_data, translate_map, translate_data, current_key ): for index, item in enumerate(source_data): for map_key in translate_map: if isinstance(map_key, str): key = ".".join([current_key, str(item["id"]), map_key]) if translate_data.get(key): item[map_key] = translate_data[key] elif isinstance(map_key, tuple): v_key = map_key[0] key = ".".join([current_key, str(item["id"]), map_key[0]]) value = item[v_key] new_map_key = map_key[1] source_data[index][v_key] = self.merge_translate_data( value, new_map_key, translate_data, key ) return source_data def merge_translate_key_values( self, source_data: dict, translate_data: dict, country_key: str ): country_diff_prefix = "country_diff_" current_country_diff_prefix = f"country_diff_{country_key}." for key, value in list(translate_data.items()): if key.startswith(country_diff_prefix): if not key.startswith(current_country_diff_prefix): del translate_data[key] else: new_key = key[len(current_country_diff_prefix) :] translate_data[new_key] = value del translate_data[key] for key, _value in list(source_data.items()): value = copy.deepcopy(_value) if key in self.translate_maps and isinstance(value, list): translate_map = self.translate_maps[key] data = self.merge_translate_data( value, translate_map, translate_data, key ) source_data[key] = data return source_data
使用:
data_2 = {
"address_lists": [
{
"id": "1",
"level": "1",
"name": "亚洲",
"countrys": [
{
"id": "7",
"level": "2",
"name": "中国",
"regions": [
{
"id": "247",
"level": "3",
"name": "北京"
},
{
"id": "248",
"level": "3",
"name": "天津"
}
]}
]
},
{
"id": "156",
"level": "1",
"name": "Antarctica",
"countrys": [
{
"id": "157",
"level": "2",
"name": "South Georgia and South Sandwich Islands",
"regions": [
]
},
{
"id": "169",
"level": "2",
"name": "Georgia",
"regions": [
]
}
]
}
]}
from core.config_converter import ConfigConverter
# cc = ConfigConverter()
# data = cc.merge_translate_key_values(data_2, data_3, "")
# print(data)
cc = ConfigConverter()
translate_data = {}
cc.gen_translate_key_values(dict_1, translate_data)
print(translate_data)
2.嵌套字典比较取不同
def compare_list_value(dict1, dict2): diff_dict1 = {} diff_dict2 = {} for key in dict1: if key in dict2: if isinstance(dict1[key], list) and isinstance(dict2[key], list): diff_dict1[key] = [] diff_dict2[key] = [] for i, item1 in enumerate(dict1[key]): if i < len(dict2[key]): item2 = dict2[key][i] if item1 != item2: if isinstance(item1, dict) and isinstance(item2, dict): diff_item1 = { k: v for k, v in item1.items() if item1.get(k) != item2.get(k) } diff_item2 = { k: v for k, v in item2.items() if item2.get(k) != item1.get(k) } if diff_item1: diff_dict1[key].append(diff_item1) if diff_item2: diff_dict2[key].append(diff_item2) else: diff_dict1[key].append(item1) diff_dict2[key].append(item2) else: diff_dict1[key].append(item1) if len(dict2[key]) > len(dict1[key]): diff_dict2[key].extend(dict2[key][len(dict1[key]) :]) else: if dict1[key] != dict2[key]: diff_dict1[key] = dict1[key] diff_dict2[key] = dict2[key] else: diff_dict1[key] = dict1[key] for key in dict2: if key not in dict1: diff_dict2[key] = dict2[key] return diff_dict1, diff_dict2
每天逼着自己写点东西,终有一天会为自己的变化感动的。这是一个潜移默化的过程,每天坚持编编故事,自己不知不觉就会拥有故事人物的特质的。 Explicit is better than implicit.(清楚优于含糊)