Python代码运行出现非预期输出的排查与修复方案
问题根因
Python中字典属于可变引用类型,你的代码在给big_ds的不同mail_id键赋值时,所有键都指向了同一个提前定义的empty_dict实例,没有生成独立副本。后续不管修改哪个mail_id对应的字典,本质都是修改同一个内存里的字典对象,最终两个键对应的字典内容会完全一致,和预期不符。
问题出在这段赋值逻辑:
empty_dict = {} for query_word in query_words: empty_dict.update({query_word:[]}) for mail_id in mail_ids: big_ds.update({mail_id:empty_dict})
两次循环都把同一个empty_dict的引用绑定到了不同的mail_id上,相当于两个地址指向同一个房间,对房间内内容的所有修改,两个地址访问时都会看到。
修复方案
给每个mail_id分配独立的字典实例即可,两种常用实现方式:
方式1:遍历
mail_id时单独初始化对应字典
去掉全局复用的empty_dict,在循环内为每个邮件id生成全新的字典对象:query_words = ['probabilistic'] query_word_to_synonym_dict = {'probabilistic': ['probabilistic', 'algorithms']} mail_ids = {83, 108} big_ds = {} index = {'probabilistic':{(108, 1)}, 'algorithms':{(83, 1)}} for mail_id in mail_ids: # 每个mail_id对应独立的新字典 mail_mapping = {} for query_word in query_words: mail_mapping[query_word] = [] big_ds[mail_id] = mail_mapping for query_word in query_words: syns = query_word_to_synonym_dict[query_word] for syn in syns: index_of_word = index[syn] tuple_first = [t[0] for t in index_of_word] for number in tuple_first: big_ds[number][query_word].append(syn) print(big_ds)运行输出为预期结果:
{83: {'probabilistic': ['algorithms']}, 108: {'probabilistic': ['probabilistic']}}方式2:对模板字典做浅拷贝
如果要保留提前初始化模板字典的逻辑,赋值时传入字典的浅拷贝即可,不需要复用原对象:# 初始化模板字典 template_dict = {q: [] for q in query_words} for mail_id in mail_ids: # 每次传入副本,不直接引用原模板 big_ds[mail_id] = template_dict.copy()当前场景下字典的值是列表,浅拷贝已经可以满足独立字典的需求;如果存在多层嵌套的可变对象,再使用
copy.deepcopy()做深拷贝即可。
内容的提问来源于stack exchange,提问作者jj050102
相关产品推荐
相关产品推荐

