Python:向嵌套defaultdict追加字典列表时触发KeyError
解决Python嵌套字典存储工单列表的KeyError问题
我太懂你这个痛点了——本来存单个工单字典好好的,想改成一个客户对应多个工单的列表就炸KeyError,核心原因就是当你第一次处理某个客户的工单时,这个客户的字典条目还没初始化,直接去访问data[id]['ticket']肯定找不到键呀。下面给你两种靠谱的解决方案:
方案1:先初始化所有客户条目(最稳妥)
先把客户表的所有数据读进字典,并且给每个客户提前建好空的ticket列表,之后再把工单一个个加进去,这样就不会出现找不到键的情况了。
完整代码示例
import pandas as pd # 读取你的两个CSV文件(替换成实际文件名) customers_df = pd.read_csv('customers.csv') tickets_df = pd.read_csv('tickets.csv') # 初始化最终的嵌套字典 customer_data = {} # 第一步:先把所有客户的基础信息存入字典,同时初始化ticket为空列表 for _, customer_row in customers_df.iterrows(): cust_id = customer_row['customer_id'] # 替换成你实际的客户ID列名 # 构建客户的基础字典,记得加上空的ticket列表 customer_data[cust_id] = { 'name': customer_row['name'], # 替换成你客户表的实际字段 'email': customer_row['email'], # 其他客户字段... 'ticket': [] # 关键:提前初始化工单列表 } # 第二步:遍历工单表,把每个工单加到对应客户的ticket列表里 for _, ticket_row in tickets_df.iterrows(): cust_id = ticket_row['customer_id'] # 工单表关联客户ID的列名 # 把工单行转成字典 ticket_dict = ticket_row.to_dict() # 先检查客户ID是否存在(避免无效工单报错) if cust_id in customer_data: customer_data[cust_id]['ticket'].append(ticket_dict) else: print(f"注意:工单对应的客户ID {cust_id} 不存在于客户表中") # 可以打印看看结果 print(pd.json_normalize(customer_data.values()).head())
方案2:用defaultdict自动初始化(更简洁)
如果你不想手动初始化所有客户,Python的collections.defaultdict可以帮你自动创建不存在的客户条目,并且自动给ticket设为空列表,代码会更简洁:
代码示例
import pandas as pd from collections import defaultdict # 用defaultdict自动初始化:当访问不存在的客户ID时,自动创建带空ticket的字典 customer_data = defaultdict(lambda: {'ticket': []}) # 先填充客户的基础信息 for _, customer_row in customers_df.iterrows(): cust_id = customer_row['customer_id'] # 把客户信息更新到字典里,不会覆盖已有的ticket列表 customer_data[cust_id].update(customer_row.to_dict()) # 再添加工单 for _, ticket_row in tickets_df.iterrows(): cust_id = ticket_row['customer_id'] customer_data[cust_id]['ticket'].append(ticket_row.to_dict()) # 转成普通字典(可选,如果你不需要defaultdict的特性了) customer_data = dict(customer_data)
关键注意点
- 一定要确保客户表和工单表的关联列(比如
customer_id)名称一致,否则会匹配不上。 - 如果工单表中有客户表不存在的ID,方案1会打印警告,方案2会自动创建一个只有
ticket列表的空客户条目,你可以根据实际需求调整处理逻辑。
内容的提问来源于stack exchange,提问作者KevKosDev
相关产品推荐
相关产品推荐

