Python 容器类型 defaultdict,给字典提供默认值

python 字典获取 key 报错怎么办?

1 字典值获取

在 python 语言当中,经常会用到 dict 字典这种数据类型。当在字典当中获取一个不存在的 key 时,会引发异常。比如在下面这个例子当中,gender 这个 key 在字典当中不存在,如果强行访问就会报错。

#------- 正常字典报错 
user = {"name": "Lisa", "age": 18}
user["gender"]

报错信息:

    ----------------------------------------------------
    KeyError Traceback (most recent call last)

    <ipython-input-24-1625da51ebd2> in <module>
          1 #------- 正常字典报错
          2 user = {"name": "Lisa", "age": 18}
    ----> 3 user["gender"]

    KeyError: 'gender'

这给访问数据的时候造成一定的困扰,我们需要频繁的用类似 if "gender" in user 这样的判断语句去判断。

为了解决这个问题,可以通过 user.get(“gender”, “默认值”) 的方式获取 key, 当 key 不存在时,赋给一个默认值。

gender = user.get("gender", "未知")
# gender ==> 未知

2 defaultdict

采用 get 方法虽然从一定程度上解决了报错问题,但是如果有很多数据需要频繁去获取还是不够方便,比如要进行大量数据分析的时候。

这时候我们可以使用 defaultdict, 他提供一个位置参数和不定长参数。位置参数是设置默认值的工厂函数。内置的通常是常用的数据类型转化函数:

  • int
  • str
  • list
  • tuple
  • dict 等等。
#--- 普通字典转化成 defaultdict, 提供默认值
from collections import defaultdict

user_default_value = defaultdict(int, user)
user_default_value["gender"]

# 此时得到默认值 0

3 defaultdict 参数说明

  • defaultdict 第一个参数是默认值的工厂函数
  • 后面的 **kw 是键值对, 也可以是整个字典,或者不加。
#-------关键字参数
user_default_value = defaultdict(int, **user)
user_default_value["gender"]
# 传入字典
user_default_value = defaultdict(int, user)
user_default_value["gender"]

4 工厂函数的几种形式

工厂函数可以是以下几种类型:

  • 内置数据转化函数
  • 匿名函数, 匿名函数不需要传入值。 比如 lambda : 3
  • 自定义函数。自定义函数可以有参数,也可以不传参数。
#-------函数名
user_default_value = defaultdict(str, user)
user_default_value["gender"]

# 结果:''

匿名函数的形式:

#----------匿名函数
user_default_value = defaultdict(lambda : "", user)
user_default_value["gender"]

# 结果:''

也可以自己定义函数, 函数也不需要传递参数:

# yz-------自定义函数不穿参数
def default_value():
    return "NaN"

user_default_value = defaultdict(default_value, user)
user_default_value["gender"]

# 结果:'NaN'

有时候如果需要指定某个业务赋一个默认值,另一个业务赋另一个默认值,由参数去控制,则可以在自定义函数当中加入参数。

# yz-----自定义函数传递参数
# 当需要根据具体的业务指定返回值是可以使用
def default_value(model):
    defaults = {
        "list": [],
        "dict": {},
        "str": "",
        "int": 0
    }
    return defaults.get(model, None)

user_default_value = defaultdict(lambda:default_value("dict"), user)
user_default_value["gender"]

# 结果 {}

5, defaultdict 原理

defaultdict 访问不存在的 key 而不报错的原理是通过类当中的 __missing__ 方法控制,下面是一个简单版的自己定义的 defaultdict 类:

```python
class defaultdict(dict):
def init(self, defaultfactory=None, args, *kw):
super()._init
(args, *kw)
self.default_factory = default_factory

def __getitem__(self, key):
    try:
        return super().__getitem__(key)
    except KeyError:
        return self.__missing__(key)

def __missing__(self, key):
    self[key] = value = self.default_factory
    if callable(self.default_factory):
        self[key] = value = self.default_factory()
    return value
posted @ 2020-08-11 10:05  王雨泽  阅读(1573)  评论(0编辑  收藏  举报