Python如何对比键名未知的JSON文件中的取值差异
JSON条目对比解决方案
你的核心难点是两个平台的键名存在格式、别名差异,无法直接按键名匹配对比,可以按照以下步骤处理:
1. 先做键名归一化
提前统一不同写法的同类型字段,规则可根据你的实际数据补充:
- 赛事名称:提取核心关键词匹配,只要同时包含费城/Philadelphie和亚特兰大/Atlanta相关关键词就判定为同一场赛事
- 投注分类:提取核心规则匹配,比如包含「Points + Rebonds + Passes」就判定为球员得分+篮板+助攻类投注
- 投注项:
- 球员名统一映射:比如
Clint Capela对应C.Capela,John Collins对应J.Collins - 数值格式统一:把法语格式的逗号小数点替换为英文格式,比如
24,5转成24.5 - 描述统一:去掉冗余修饰词,比如「de」等无意义助词
- 球员名统一映射:比如
2. 用脚本遍历匹配对比
可以直接用Python实现,示例代码如下:
import json import re # 预设映射规则,可根据实际数据补充 player_map = { "Clint Capela": "C.Capela", "John Collins": "J.Collins", "Kevin Huerter": "K.Huerter", "Trae Young": "Tr.Young" } bet_type_map = { "Performance du Joueur (Points + Rebonds + Passes)": "Performance du Joueur - Total Points + Rebonds + Passes - Match" } def normalize_bet_item(name): # 统一数值格式 name = name.replace(",", ".") # 替换球员全称为缩写 for full_name, short_name in player_map.items(): name = name.replace(full_name, short_name) # 去掉冗余助词 name = re.sub(r"\s+de\s+", " ", name) return name.strip() def compare_bet_data(unibet_data, parions_data): diff_result = [] # 遍历Unibet条目找缺失/赔率差异 for ub_event in unibet_data.values(): # 示例默认单场赛事,多赛事可加关键词匹配逻辑 ps_event = next(iter(parions_data.values())) for ub_bet_type, ub_bet_items in ub_event.items(): if ub_bet_type not in bet_type_map: continue ps_bet_type = bet_type_map[ub_bet_type] ps_bet_items = ps_event.get(ps_bet_type, {}) # 对比单个投注项 for ub_item, ub_odds in ub_bet_items.items(): norm_ub = normalize_bet_item(ub_item) ps_odds = None for ps_item, po in ps_bet_items.items(): if normalize_bet_item(ps_item) == norm_ub: ps_odds = po break if ps_odds is None: diff_result.append(f"Parions Sport 缺失投注项:{ub_item} | Unibet赔率:{ub_odds}") elif abs(ub_odds - ps_odds) > 0.001: diff_result.append(f"赔率差异:{ub_item} | Unibet:{ub_odds} | Parions Sport:{ps_odds}") # 遍历Parions条目找Unibet缺失的投注项 for ps_event in parions_data.values(): ub_event = next(iter(unibet_data.values())) for ps_bet_type, ps_bet_items in ps_event.items(): ub_bet_type = next((k for k, v in bet_type_map.items() if v == ps_bet_type), None) if not ub_bet_type: continue ub_items_norm = [normalize_bet_item(i) for i in ub_event.get(ub_bet_type, {}).keys()] for ps_item, ps_odds in ps_bet_items.items(): if normalize_bet_item(ps_item) not in ub_items_norm: diff_result.append(f"Unibet 缺失投注项:{ps_item} | Parions Sport赔率:{ps_odds}") return diff_result if __name__ == "__main__": with open("你的JSON文件路径.json", "r", encoding="utf-8") as f: all_data = json.load(f) diffs = compare_bet_data(all_data["Unibet"], all_data["Parions Sport"]) for d in diffs: print(d)
3. 运行输出结果
替换代码中的JSON文件路径后运行,即可输出三类差异:
- Unibet存在但Parions Sport不存在的投注项
- Parions Sport存在但Unibet不存在的投注项
- 同一投注项赔率不一致的记录
如果后续数据量增大,可加入模糊匹配算法(比如编辑距离、Jaccard相似度)自动匹配键名,无需手动维护映射表。
内容的提问来源于stack exchange,提问作者Lucas
相关产品推荐
相关产品推荐

