Python嵌套字典使用copy仍被覆盖的问题排查与解决
嵌套字典拷贝后更新异常?问题出在浅拷贝上!
嘿,这问题我之前踩过坑!你用dict.copy()还是出现所有日期同小时的alloted值一起变,核心原因是字典的copy()是浅拷贝(shallow copy)——它只会复制最外层的字典结构,嵌套的子字典其实还是共享同一个引用对象。
为啥你的代码会出问题?
看你初始化的逻辑:
- 你先创建了
hour_to_allotflag,里面每个hour对应一个{'alloted': False}; - 然后给每个day赋值
hour_to_allotflag.copy()——这步是浅拷贝,意味着每个day里的hour字典,和原hour_to_allotflag里的hour字典是同一个对象; - 最后给每个教员赋值
day_to_hour.copy()——同样是浅拷贝,所有教员的day字典也共享同一批引用。
所以当你修改某一个教员某一天某小时的alloted值时,你实际上修改的是所有day、所有教员共享的那个子字典,自然所有地方都会跟着变。
怎么解决?
有两种靠谱的方式,都能彻底切断引用共享:
方式1:手动逐层创建新字典(最直观,性能也不错)
直接在每个循环里创建全新的字典,确保每个嵌套层级都是独立的对象,完全避免引用问题:
self.faculty_to_day_hour_slot_map = {} for faculty_object in self.faculties: # 为当前教员创建专属的日期-小时映射 day_to_hour = {} for day in ['mon', 'tue', 'wed', 'thu', 'fri', 'sat']: # 为当前日期创建专属的小时-分配状态映射 hour_map = {} for hour in range(1, 9): # 每个小时都创建全新的状态字典 hour_map[hour] = {'alloted': False} day_to_hour[day] = hour_map self.faculty_to_day_hour_slot_map[faculty_object.id] = day_to_hour
方式2:用copy.deepcopy()递归拷贝
如果觉得手动写多层循环麻烦,可以用Python标准库copy里的deepcopy(),它会递归复制所有嵌套的对象,确保每个层级都是全新的:
import copy # 先创建一个基础模板 base_template = {} for day in ['mon', 'tue', 'wed', 'thu', 'fri', 'sat']: base_template[day] = {hour: {'alloted': False} for hour in range(1,9)} self.faculty_to_day_hour_slot_map = {} for faculty_object in self.faculties: # 深拷贝模板,给每个教员生成独立的结构 self.faculty_to_day_hour_slot_map[faculty_object.id] = copy.deepcopy(base_template)
验证一下
修改之后,再执行:
self.faculty_to_day_hour_slot_map.get('uniqueid').get('mon').get(1)['alloted'] = True
就只会把uniqueid教员的周一1点的alloted设为True,其他日期、其他教员的对应hour值完全不受影响啦!
内容的提问来源于stack exchange,提问作者Natesh bhat
相关产品推荐
相关产品推荐

