0

0

Python中嵌套字典赋值时的浅拷贝陷阱与正确解决方案

霞舞

霞舞

发布时间:2026-03-16 17:51:01

|

797人浏览过

|

来源于php中文网

原创

Python中嵌套字典赋值时的浅拷贝陷阱与正确解决方案

本文详解Python中因误用可变对象(如字典)导致嵌套结构“所有键共享同一值”的典型问题,指出根本原因是多次引用同一字典对象,并提供.copy()、字典推导式及defaultdict等专业级修复方案。

本文详解python中因误用可变对象(如字典)导致嵌套结构“所有键共享同一值”的典型问题,指出根本原因是多次引用同一字典对象,并提供`.copy()`、字典推导式及`defaultdict`等专业级修复方案。

在Python数据处理中,构建按日期分组的嵌套统计字典(如data_dict[date][category] += 1)是常见需求。但若初始化方式不当,极易触发“修改一处、全盘生效”的异常行为——正如示例中对 '2022-03-07' 的更新,却意外影响了所有日期下的 'POLITICAL ACTION COMMITTEE' 计数。其根源在于:字典是可变对象,直接赋值仅传递引用,而非创建独立副本

回顾原代码的关键问题段:

contribution_dict = {"INDIVIDUAL": 0, 'ORGANIZATION': 0, 'POLITICAL ACTION COMMITTEE': 0, 
                     'CANDIDATE': 0, 'OTHER COMMITTEE': 0, 'CAMPAIGN COMMITTEE': 0}

for all_values in range(len(list)):
    data_dict[str(list[all_values])] = contribution_dict  # ❌ 危险:所有键指向同一字典对象

此处 contribution_dict 在循环中被重复赋值给 data_dict 的不同键,但实际所有键都指向内存中同一个字典实例。因此,任何一次 += 操作(如 data_dict['2022-03-07']['POLITICAL ACTION COMMITTEE'] += 1)都会修改该共享对象,造成“全局污染”。

阿里妈妈·创意中心
阿里妈妈·创意中心

阿里妈妈营销创意中心

下载

✅ 正确解决方案

方案1:使用 .copy() 创建浅拷贝(推荐用于简单字典)

for date_obj in list:
    data_dict[str(date_obj)] = contribution_dict.copy()  # ✅ 每个键获得独立副本

✅ 优点:简洁、易理解;适用于字典值均为不可变类型(如int, str)的场景。
⚠️ 注意:若contribution_dict的值本身是可变对象(如嵌套列表或字典),需改用 copy.deepcopy()。

方案2:字典推导式(更Pythonic)

data_dict = {str(date_obj): contribution_dict.copy() for date_obj in list}

方案3:使用 collections.defaultdict 动态初始化(适合增量更新场景)

from collections import defaultdict

# 初始化:每个日期自动关联一个独立的计数字典
data_dict = defaultdict(lambda: contribution_dict.copy())

# 后续可安全操作
data_dict['2022-03-07']['POLITICAL ACTION COMMITTEE'] += 1  # ✅ 仅影响该日期

? 验证修复效果

添加调试代码确认各日期字典是否真正独立:

立即学习Python免费学习笔记(深入)”;

# 检查内存地址是否不同
print(id(data_dict['2022-03-07']))      # → 例如: 140234567890123
print(id(data_dict['2022-03-08']))      # → 应为不同地址,如: 140234567890456

? 关键总结

  • 根本原则:可变对象(list, dict, set)赋值即引用,需显式拷贝才能隔离修改。
  • 避免反模式:切勿在循环中重复赋值同一可变对象给不同键。
  • 生产建议:优先使用字典推导式或 defaultdict,兼顾可读性与健壮性;对深层嵌套结构,务必评估是否需要 deepcopy。
  • 延伸思考:此问题同样存在于列表推导中(如 [my_list] * n),本质是Python对象模型的核心特性,理解它能规避大量隐蔽bug。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1071

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

617

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

335

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

235

2025.08.29

chatgpt使用指南
chatgpt使用指南

本专题整合了chatgpt使用教程、新手使用说明等等相关内容,阅读专题下面的文章了解更多详细内容。

0

2026.03.16

chatgpt官网入口地址合集
chatgpt官网入口地址合集

本专题整合了chatgpt官网入口地址、使用教程等内容,阅读专题下面的文章了解更多详细内容。

0

2026.03.16

minimax入口地址汇总
minimax入口地址汇总

本专题整合了minimax相关入口合集,阅读专题下面的文章了解更多详细地址。

4

2026.03.16

C++多线程并发控制与线程安全设计实践
C++多线程并发控制与线程安全设计实践

本专题围绕 C++ 在高性能系统开发中的并发控制技术展开,系统讲解多线程编程模型与线程安全设计方法。内容包括互斥锁、读写锁、条件变量、原子操作以及线程池实现机制,同时结合实际案例分析并发竞争、死锁避免与性能优化策略。通过实践讲解,帮助开发者掌握构建稳定高效并发系统的关键技术。

7

2026.03.16

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

114

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 5.1万人学习

SciPy 教程
SciPy 教程

共10课时 | 2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号