当前位置: 首页 > news >正文

Python defaultdict 的强大之处:告别繁琐的字典键检查: Effective Python 第17条

在 Python 编程中,字典是一种非常灵活和强大的数据结构,允许我们存储键值对。然而,当需要处理不存在的键时,我们可能会遇到一些挑战。defaultdict 是 Python collections 模块中的一个类,它能够自动为缺失的键分配默认值,从而简化了字典操作。本文将通过具体的例子来展示 defaultdict 的用法和优势。

问题背景

假设我们有一个需求,要记录一个人去过的国家和城市。我们可以使用一个字典来实现,其中键是国家,值是一个集合,集合中包含该国家访问过的城市。

使用 setdefault 的方式

一种常见的做法是使用 setdefault 方法。该方法会在键不存在时,为该键设置一个默认值,然后返回该键对应的值。

visits = {'Mexico': {'Tulum', 'Puerto Vallarta'},'Japan': {'Hakone'},
}visits.setdefault('France', set()).add('Arles')
if (japan := visits.get('Japan')) is None:visits['Japan'] = japan = set()
japan.add('Kyoto')

这种方法虽然可行,但代码不够直观,且每次调用 add 方法时,即使键已存在,也会创建一个新的 set 实例,这显然是不高效的。

使用 defaultdict 优化

Python 的 collections 模块提供了一个名为 defaultdict 的类,它能够解决这个问题。defaultdict 允许我们在键不存在时,自动为该键分配一个默认的值。这样我们就不需要检查键是否存在,也不需要手动设置默认值。

下面是如何使用 defaultdict 来重构前面的例子:

from collections import defaultdictclass Visits:def __init__(self):# 使用 defaultdict 自动创建缺失的集合self.data = defaultdict(set)def add(self, country, city):# 直接添加城市到国家的集合中self.data[country].add(city)visits = Visits()
visits.add('England', 'Bath')
visits.add('England', 'London')
visits.add('France', 'Paris')
visits.add('France', 'Lyon')
visits.add('Japan', 'Tokyo')
visits.add('Japan', 'Kyoto')
visits.add('Japan', 'Osaka')
visits.add('Italy', 'Rome')
visits.add('Italy', 'Venice')print(visits.data)

打印结果:

defaultdict(<class 'set'>, {'England': {'Bath', 'London'},'France': {'Paris', 'Lyon'},'Japan': {'Tokyo', 'Kyoto', 'Osaka'},'Italy': {'Rome', 'Venice'}
})

实际应用中的 defaultdict 例子

让我们通过几个具体的例子来看看 defaultdict 如何在真实世界的应用中发挥作用。

例1:单词计数

class WordCounter:def __init__(self):self.word_counts = defaultdict(int)def process_text(self, text):words = text.split()for word in words:self.word_counts[word] += 1word_counter = WordCounter()
word_counter.process_text("Hello world! Hello everyone.")
print(word_counter.word_counts)

打印结果:

defaultdict(<class 'int'>, {'Hello': 2, 'world!': 1, 'everyone.': 1})

例2:用户活动跟踪

class UserActivity:def __init__(self):self.activity = defaultdict(set)def log_activity(self, user, page):self.activity[user].add(page)user_activity = UserActivity()
user_activity.log_activity('user1', '/home')
user_activity.log_activity('user1', '/about')
user_activity.log_activity('user2', '/contact')print(user_activity.activity)

打印结果:

defaultdict(<class 'set'>, {'user1': {'/home', '/about'}, 'user2': {'/contact'}})

例3:购物车

class ShoppingCart:def __init__(self):self.cart = defaultdict(int)def add_item(self, user, item):self.cart[(user, item)] += 1shopping_cart = ShoppingCart()
shopping_cart.add_item('user1', 'apple')
shopping_cart.add_item('user1', 'banana')
shopping_cart.add_item('user2', 'apple')print(shopping_cart.cart)

打印结果:

defaultdict(<class 'int'>, {('user1', 'apple'): 1, ('user1', 'banana'): 1, ('user2', 'apple'): 1})

结论

通过上述例子,我们可以看到 defaultdict 在处理需要动态创建字典键的情况时的便利性和效率。它简化了代码,减少了错误,并且提高了性能。在处理动态数据结构时,defaultdict 是一个值得推荐的工具。通过使用 defaultdict,我们可以写出更简洁、更易读、更高效的代码。

http://www.lryc.cn/news/603095.html

相关文章:

  • days34:零基础学嵌入式之数据存储——数据库
  • Sentinel 不同层面的流控保护
  • Java中实现定时任务执行的方式总结
  • 反欺诈系统:Oracle 到 ES 迁移实战
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 微博文章数据可视化分析-点赞区间实现
  • Java类加载机制详解
  • AI coding汇总持续更新
  • STM32启动流程
  • 【学习路线】Android开发2025:从入门到高级架构师
  • Unity_UI_NGUI_锚点组件
  • 【java面试day7】redis分布式锁
  • SpringBoot 发送邮件
  • 五自由度磁悬浮轴承转子不平衡质量的高性能控制策略全解析
  • 算法训练营day34 动态规划② 62.不同路径、63. 不同路径 II、343整数拆分、96.不同的二叉搜索树
  • Java响应式编程
  • ATF 运行时服务
  • ros2的package.xml和rosdep
  • 基于深度学习的医学图像分析:使用3D CNN实现肿瘤检测
  • 第十天:字符菱形
  • 一个Pycharm窗口添加多个项目来满足运行多个项目的需求
  • DDoS攻击防御:从5G到T级防护方案全对比
  • 企业级日志分析系统ELK
  • Python动态规划:从基础到高阶优化的全面指南(3)
  • 历史版本的vscode下载地址
  • 实验-静态路由
  • 智慧工地系统:科技赋能建筑新未来
  • 学习dify:一个开源的 LLM 应用开发平台
  • 【GitHub Workflows 基础(二)】深入理解 on、jobs、steps 的核心语法与执行逻辑
  • 【2025/07/28】GitHub 今日热门项目
  • 【iOS】类和分类的加载过程