如何向双层嵌套字典追加内容而非覆盖原有数据?
双层嵌套字典追加错误信息避免覆盖的解决办法
问题场景
现有一个双层嵌套字典errors,已成功写入格式错误信息,但在添加必填字段空值/NaN错误时,原有数据被全部覆盖,需要实现仅追加新错误,保留原有数据的效果。
现有代码及问题
初始数据与格式错误写入代码
import pandas as pd data= {'First Name': ['Sally', 'Bob', 'Sue', 'Tom', 'Will'], 'Last Name': ['William', '', 'Wright', 'Smith','Thomas'], 'Email Address':['sally@gmail.co.uk','bobby123@gmail.com','suewright_123@yahoo.gov','tom.smith23@students.wacs.fl.us',''], 'Industry': ['Automotive','Gas', 'Healthcare', 'Other', 'Biotech / Pharma'], 'SME Vertical': ['Education', 'hotels', '', 'project management and design',''], 'System Type': ['Access','Access','video Systems','Access','Access'], 'Account Type': ['Commercial', '','Reseller','','Small']} df=pd.DataFrame(data) df1= df[["Industry",'System Type','Account Type', 'SME Vertical']] req_cols= ['First Name','Last Name','Email Address'] errors= {} filename = "Data Template" # 假设filename为该值 errors[filename]={} # 写入格式错误信息(运行正常) mask = df1.apply(lambda c: c.isin(valid[c.name])) # valid为外部JSON读取的有效值字典 df1.mask(mask|df1.eq(' ')).stack() for err_i, (r, v) in enumerate(df1.mask(mask|df1.eq(' ')).stack().iteritems()): errors[filename][err_i] = {"row": r[0], "column": r[1], "message": v + " is invalid"}
导致覆盖的必填字段错误写入代码
bad_nan = df.loc[df[req_cols].isna().any(1)] bad_nan=bad_nan.fillna(value='NaN' ) for col in bad_nan.columns: for i in bad_nan.index: if bad_nan.loc[i, col] == 'NaN': # 此处直接赋值替换了整个errors[filename]字典,导致原有数据丢失 errors[filename]={ "row": i, "column": col, "message": "This is a required field" }
错误原因
上述代码中errors[filename] = {...}是直接替换errors[filename]对应的整个字典对象,而非在已有字典中添加新的键值对,因此原有格式错误数据被完全覆盖。
解决方案
要实现追加,需先获取当前errors[filename]中已有的条目数量,以此作为新错误条目的起始索引,确保新条目添加到已有字典的末尾:
# 修正后的必填字段错误写入代码 bad_nan = df.loc[df[req_cols].isna().any(1)] bad_nan = bad_nan.fillna(value='NaN') # 获取当前已有的错误条目数,作为新条目的起始索引 start_idx = len(errors[filename]) for col in req_cols: # 仅遍历必填字段,减少不必要的循环 for i in bad_nan.index: if bad_nan.loc[i, col] == 'NaN': # 用start_idx递增的方式添加新条目,避免覆盖 errors[filename][start_idx] = { "row": i, "column": col, "message": "This is a required field" } start_idx += 1
优化说明
- 仅遍历
req_cols(必填字段),减少不必要的循环 - 通过
len(errors[filename])获取当前错误条目数,确保新条目从下一个索引开始添加 - 每添加一个条目后递增
start_idx,保证键值唯一,避免覆盖已有条目
效果验证
修改后,errors[filename]将同时包含原有格式错误和新增的必填字段空值错误,达到预期的共存效果:
key Type Size Value Data Template dict 8 {'row': 1, 'column': 'Industry', 'message': 'gas is invalid'} {'row': 1, 'column': 'SME Vertical', 'message': 'hotels is invalid'} {'row': 2, 'column': 'Industry', 'message': 'healthcare is invalid'} {'row': 3, 'column': 'Industry', 'message': 'other is invalid'} {'row': 3, 'column': 'SME Vertical', 'message': 'project management and design is invalid'} {'row': 4, 'column': 'Account Type', 'message': 'small is invalid'} {'row': 2, 'column' : 'Last Name', 'message': 'this is a required field'} {'row': 4, 'column' : 'Email Address', 'message': 'this is a required field'}
内容的提问来源于stack exchange,提问作者user19702551
相关产品推荐
相关产品推荐

