1. 程式人生 > 實用技巧 >Python 容器型別 defaultdict,給字典提供預設值

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