python -- Handling Missing Keys in Dictionaries

2022/7/8 14:22:57

本文主要是介绍python -- Handling Missing Keys in Dictionaries,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Background

对于一些场景, 我们要求词典对于不存在的key,不报错,返回默认值。

dict有处理方法, get 方法 或者 setdefault方法。

但是过于繁琐。

 

Handling Missing Keys in Dictionaries

https://realpython.com/python-defaultdict/#handling-missing-keys-in-dictionaries

dict有处理方法对缺失key的处理。

A common issue that you can face when working with Python dictionaries is how to handle missing keys. If your code is heavily based on dictionaries, or if you’re creating dictionaries on the fly all the time, then you’ll soon notice that dealing with frequent KeyError exceptions can be quite annoying and can add extra complexity to your code. With Python dictionaries, you have at least four available ways to handle missing keys:

  1. Use .setdefault()
  2. Use .get()
  3. Use the key in dict idiom
  4. Use a try and except block

setdefault(key[, default])

If key is in the dictionary, return its value. If not, insert key with a value of default and return default. default defaults to None.

get(key[, default])

Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError.

 

>>> a_dict = {}
>>> a_dict['missing_key']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    a_dict['missing_key']
KeyError: 'missing_key'
>>> a_dict.setdefault('missing_key', 'default value')
'default value'
>>> a_dict['missing_key']
'default value'
>>> a_dict.setdefault('missing_key', 'another default value')
'default value'
>>> a_dict
{'missing_key': 'default value'}

 

Understanding the Python defaultdict Type

collection库的defaultdict是dict的一个子类

在defaultdict初始化方法中,设置缺失元素的创建方法, 此创建方法,存储在 default_factory属性。

 

The Python standard library provides collections, which is a module that implements specialized container types. One of those is the Python defaultdict type, which is an alternative to dict that’s specifically designed to help you out with missing keys. defaultdict is a Python type that inherits from dict:

 

>>> from collections import defaultdict
>>> issubclass(defaultdict, dict)
True

 

The main difference between defaultdict and dict is that when you try to access or modify a key that’s not present in the dictionary, a default value is automatically given to that key. In order to provide this functionality, the Python defaultdict type does two things:

  1. It overrides .__missing__().
  2. It adds .default_factory, a writable instance variable that needs to be provided at the time of instantiation.

The instance variable .default_factory will hold the first argument passed into defaultdict.__init__(). This argument can take a valid Python callable or None. If a callable is provided, then it’ll automatically be called by defaultdict whenever you try to access or modify the value associated with a missing key.

 

>>> # Correct instantiation
>>> def_dict = defaultdict(list)  # Pass list to .default_factory
>>> def_dict['one'] = 1  # Add a key-value pair
>>> def_dict['missing']  # Access a missing key returns an empty list
[]
>>> def_dict['another_missing'].append(4)  # Modify a missing key
>>> def_dict
defaultdict(<class 'list'>, {'one': 1, 'missing': [], 'another_missing': [4]})

 

Emulating the Python defaultdict Type

用户可以定义满足自己需求的 defaultdict 类

这样方法的好处是, 用户可以在 __missing__ 方法中进行定制缺失处理逻辑。

 

例如对于缺失的key的默认值返回key小写形式,或者按照key的默认值表来返回默认值。

 

In this section, you’ll be coding a Python class that will behave much like a defaultdict. To do that, you’ll subclass collections.UserDict and then add .__missing__(). Also, you need to add an instance attribute called .default_factory, which will hold the callable for generating default values on demand. Here’s a piece of code that emulates most of the behavior of the Python defaultdict type:

 

import collections


class my_defaultdict(collections.UserDict):

    def __init__(self, default_factory=None, *args, **kwargs):

        super().__init__(*args, **kwargs)

        if not callable(default_factory) and default_factory is not None:

            raise TypeError('first argument must be callable or None')

        self.default_factory = default_factory


    def __missing__(self, key):

        if self.default_factory is None:

            raise KeyError(key)

        if key not in self:

            self[key] = self.default_factory()

        return self[key]

 

>>> from my_dd import my_defaultdict
>>> dd_one = my_defaultdict(list)
>>> dd_one
{}
>>> dd_one['missing']
[]
>>> dd_one
{'missing': []}
>>> dd_one.default_factory = int
>>> dd_one['another_missing']
0
>>> dd_one
{'missing': [], 'another_missing': 0}
>>> dd_two = my_defaultdict(None)
>>> dd_two['missing']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    dd_two['missing']
  File "/home/user/my_dd.py", line 10,
 in __missing__
    raise KeyError(key)
KeyError: 'missing'

 



这篇关于python -- Handling Missing Keys in Dictionaries的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程