百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

Python之容器:字典(dict)缺失值处理不优雅?试试defaultdict

liuian 2024-11-28 00:42 60 浏览

引言

前面我们已经介绍了Python中字典(dict)的使用,在处理字典缺失键时,一种方式是加分支判断处理,但是有点繁琐;另外一种,是使用setdefault()方法,似乎已经简化了缺失值的处理。但是,setdefault()方法,其实还是有两个问题的:
1、setdefault()这个方法的名字比较怪,对不熟悉的童鞋来说,可读性比较差,需要在脑子里绕一会儿,一时半会儿难以理解这个代码要干啥;
2、还是不够高效,代码行数似乎还可以精简

针对缺失键的场景,Python提供了更加好用的工具,这就是collections包中的defaultdict。

本文的主要内容大致如下:
1、回顾一下使用dict在应对缺失值的做法
2、defaultdict的使用

dict缺失键的常规做法

以人员按照年龄的分组计数为例,来说明缺失值的应对场景。
首先生成测试数据,然后以常规的分支判断来统计:

from faker import Faker
from rich import print
fk = Faker('zh_CN')

# 为了数据尽量聚集,我们生成18~28年龄的测试数据
persons = [(fk.unique.name(), fk.random_int(18, 28)) for _ in range(100)]
print(persons)

# 按照年龄统计人数
count_by_age = {}

# 通过判断键值是否存在,分支处理
for name, age in persons:
    if age in count_by_age:
        count_by_age[age] += 1
    else:
        count_by_age[age] = 1

print(count_by_age)

执行结果:

我们也可以试着用前面提到过的setdefault()方法来处理,可以把分支判断的代码省掉:

count_by_age = {}
# 使用setdefault()方法来处理
for name, age in persons:
    cnt = count_by_age.setdefault(age, 0)
    count_by_age[age] += 1
print(count_by_age)

虽然有点奇怪……
接下来试试defaultdict来处理。

defaultdict的使用

简单看下defaultdict的定义:

传入一个default_factory的“函数”,这个函数会在当key不存在时,被调用,用来生成一个新的默认值。

接下来,看下上面的例子,使用defaultdict的实现:

from faker import Faker
from collections import defaultdict

fk = Faker('zh_CN')

# 为了数据尽量聚集,我们生成18~28年龄的测试数据
persons = [(fk.unique.name(), fk.random_int(18, 28)) for _ in range(100)]

# 按照年龄统计人数,这次不使用dict,改用defaultdict
count_by_age = defaultdict(int)

# 通过判断键值是否存在,分支处理
for name, age in persons:
    count_by_age[age] += 1

print(count_by_age)

count_by_age2 = {}
# 使用setdefault()方法来处理
# 用来跟defaultdict处理的结果做对比
for name, age in persons:
    cnt = count_by_age2.setdefault(age, 0)
    count_by_age2[age] += 1
print(count_by_age2)
# 从定义来看,defaultdict与dict中元素相同时,比较时会返回True
print(count_by_age == count_by_age2)

执行结果:

可以看到,使用defaultdict时,我们直接通过索引的方式对不存在的key进行索引并执行更新操作,一行代码就搞定了。

其内部的实现逻辑是,首先判断key不存在时,会通过构造defaultdict对象时,传入的“函数”构造一个默认值,比如:
int()默认会创建一个值为0的整数对象,str()会创建一个值为""的字符串对象。

# 0
print(int())
# ''空字符串
print(str())
# 长度为0
print(len(str()))

其实,当需要进行分组收集时,defaultdict会更加好用。

比如,不同于前面的分组计数,我们这次要把每个年龄的人名都放在一起,放到一个list中,我们通过defaultdict来实现:

from faker import Faker
from rich import print
from collections import defaultdict

fk = Faker('zh_CN')

# 为了数据尽量聚集,我们生成18~28年龄的测试数据
persons = [(fk.unique.name(), fk.random_int(18, 28)) for _ in range(100)]

# 按照年龄分组收集
collect_by_age = defaultdict(list)

# 通过判断键值是否存在,分支处理
for name, age in persons:
    collect_by_age[age].append(name)

print(collect_by_age)

代码中,我们使用list作为工厂函数进行默认值的构造,当key不存在时,创建一个空列表对象。

执行结果:

我们还可以自定义工厂函数来指定默认值,比如,我们默认每个人的年龄都是18:

def default_age():
    return 18

persons = defaultdict(default_age)
print(persons['zs'])
persons['zs'] = 25
print(persons['zs'])

执行结果:

首次访问时,不存在,则会创建默认值18。

前面,之所以在函数上面打了引号,其实并不一定只能是函数,其实,只要是可调用的对象,比如,我们传入一个自定义类名,则会默认调用其__init__方法:

class Student:
    def __init__(self):
        self.name = 'unknown'
        self.age = 0

    def __str__(self):
        return f"Student(name: {self.name}, age: {self.age})"


stus = defaultdict(Student)
print(stus['zs'])
stus['zs'].name = '张三'
stus['zs'].age = 18
print(stus['zs'])

执行结果:

总结

关于字典中缺失值处理的场景,本文首先介绍了dict中常规的分支判断的处理方法,以及通过setdefault()简化分支处理的方法。之后,引入defaultdict,介绍了更加灵活、强大的处理方法。根据实际使用场景,可以自行选择!


相关推荐

教务网络管理系统入口(内蒙古民族大学教务网络管理系统入口)
教务网络管理系统入口(内蒙古民族大学教务网络管理系统入口)

钟山学院官网http://www.zscollege.com/钟山学院教务处http://jwc.njzs.edu.cn/钟山学院教务处学生登录入口http://jwgl.zscollege.com/jwweb/(网站左侧)三江学院的...

2025-12-28 02:05 liuian

win10系统下载32位纯净版(下载windows10纯净版)

纯净版就是最干净的版本,也叫最绿色的版本。像WIN系统通常会有纯净版、快速安装版、精简版、定制版、Ghost版等。纯净版就是只配套提供了最最基础的软件和功能,一些高级一点的功能或软件需要自己另外安装,...

联想主板进入bios的方法(联想台式机怎么进入bios)

联想电脑开机一直按F2,就可以进入BIOS,部分机型需要按Fn+F2。BIOS是英文BasicInputOutputSystem的缩略词,直译过来后中文名称就是基本输入输出系统,在IBMPC兼...

win7升级win10数据还在吗(win7升级成win10上面的数据还有吗)

在升级Windows7到Windows10的过程中,可以选择保留个人文件和应用程序,但是不保证所有数据都能完全保留。如果您选择“保留个人文件和应用程序”选项,Windows10安装...

win7怎么升级到windows10(win7怎么升级到win11系统)

Win7不够8G内存怎么升级到win10。朋友也就是说你现在在使用win7系统。内存不够8G那就是4G的呀。Windows10最低配置的内存就是4G。所以说你要把windows7升级为window...

手机桌面图标隐藏了怎么弄出来

答:手机恢复隐藏的手机图标操作步骤如下:1.首先将手机解锁后进入华为手机的桌面,双指按住桌面的上方和下方,然后由内向外滑动屏幕,呼出隐藏空间。2.在新出现的页面中,可以查看已经被隐藏的应用。3.在列出...

lol游戏崩溃是什么原因(lol游戏崩溃的原因)

1.试试重启电脑,或者是重新启动游戏。2.如果卡死了可以稍微等一下,会自动恢复。3.卡死的情况如果可以打开任务管理器,查看cpu、显卡、内存的占用率,如果异常查看对应的驱动是否正常,如果占用率都正常温...

视频工具箱怎么打开(小米视频工具箱怎么打开)

原因:系统默认隐藏了,需重新设置。方法/步骤1.点击特色功能在设置界面,点击特色功能。2.点击视频工具箱在特色功能界面,点击视频工具箱。3.开启视频工具箱在视频工具箱界面,开启视频工具箱即可。红米的视...

win7 win10配置要求(win10 win7哪个要求配置高)

要求不算高,处理器双核2.0ghz以上,4gb内存,512兆显存的显卡,这个是流畅运行Win10的基本要求。但是现在的电脑硬件性能已经远高于以上的配置,所以不用担心升级Win10后是否会卡顿的问题。不...

台式电脑配置低怎么升级(台式电脑配置升级需要换哪些东西)

1.首先查看电脑主板规格,如果规格太落后,就需要升级主板,如果主板规格较新,可以主板规格下升级其他配件2.在主板规格不变的情况下,优先升级CPU,提升CPU主频3.加大内存规格。如果主板支持的话,可以...

win10突然桌面的东西都没了(windou10桌面东西突然没了)

win10看不到正常桌面演示机型:联想GeekPro2020(系统版本:Windows10)win10看不到正常桌面是因为桌面系统图标被隐藏了,可以在个性化的主题设置中找到“桌面图标设置”,并点击...

下载清除手机垃圾免费软件(华为自带清理软件)
下载清除手机垃圾免费软件(华为自带清理软件)

手机垃圾清理软件排行:1、LBE安全大师对于这个软件,大伙都熟悉吧,它在清理手机垃圾方面很有研究,是安卓平台上首款主动式防御软件,也是第一款具备实时监控与拦截能力的安全软件,因此,深受大家的青睐和喜欢。2、猎豹清理大师猎豹清理大师(原金山清...

2025-12-27 20:55 liuian

电脑技术咨询(电脑技术在线咨询)

华为电脑关闭热门咨询的步骤如下:打开设置,然后找到通知和状态栏,点击通知智能管理,在找到有资讯热点的应用,然后关闭锁屏通知。华钜同创跨境电商服务(深圳)有限公司华钜同创跨境电商服务(深圳)有限公司成立...

dell笔记本推荐(dell笔记本电脑推荐)

灵越16plus 定位是全能本,拥有游戏本的性能,外观重量接近轻薄本,散热好,满足主流设计软件使用,玩中小型游戏无压力,还有硬件防蓝光屏幕保护眼睛~成就5320性能颜值在线,日常办公使用...

戴尔怎么进入bios设置界面(戴尔怎么进去bios设置)
  • 戴尔怎么进入bios设置界面(戴尔怎么进去bios设置)
  • 戴尔怎么进入bios设置界面(戴尔怎么进去bios设置)
  • 戴尔怎么进入bios设置界面(戴尔怎么进去bios设置)
  • 戴尔怎么进入bios设置界面(戴尔怎么进去bios设置)