深入理解 Python 字典与 defaultdict 的应用
本教程将引导你探索如何利用 Python 集合模块中的 defaultdict
,更有效地处理 Python 字典操作中可能出现的 KeyError
异常。
在 Python 中,字典作为一种内置的数据结构,以键值对的形式存储数据,允许通过键来访问对应的值。
然而,在实际应用中,当代码执行过程中存在多个字典被修改的情况时,经常会遭遇 KeyError
异常。本文将介绍几种处理此类异常的策略。
本教程的核心内容包括:
- 解析
KeyError
的本质及其产生的原因。 - 学习多种处理
KeyError
的方法。 - 掌握如何通过 Python 的
defaultdict
(dict
类的子类)优雅地处理缺失的键。
让我们开始学习吧!
Python 中的 KeyError 是什么?
在定义 Python 字典时,你需要注意以下关键点:
- 确保键的唯一性,避免重复键。
- 当使用可迭代对象作为键时,优先选择如元组等不可变集合。
只有当键实际存在于字典中时,才能通过该键访问对应的值,否则会导致 KeyError
。
考虑以下名为 books_authors
的字典,其中键为书名,值为作者姓名。
你可以在 Python REPL 中跟随本教程进行练习。
books_authors = { 'Deep Work':'Cal Newport', 'Hyperfocus':'Chris Bailey', 'Pivot':'Jenny Blake', 'The Happiness Equation':'Neil Pasricha' }
通过书名(键)可以访问作者姓名:
books_authors['Hyperfocus'] #'Chris Bailey'
使用字典对象的 items()
方法可以遍历所有键值对:
for book,author in books_authors.items(): print(f"'{book}' by {author}")
# 'Deep Work' by Cal Newport # 'Hyperfocus' by Chris Bailey # 'Pivot' by Jenny Blake # 'The Happiness Equation' by Neil Pasricha
当尝试访问字典中不存在的键时,Python 解释器会抛出 KeyError
异常。如下例子中,尝试访问 'Grit'
和 'non-existent-key'
会引发错误。
books_authors['Grit']
# --------------------------------------------------------------------------- # KeyError Traceback (most recent call last) # <ipython-input-6-e1a4486f5ced> in <module> # ----> 1 books_authors['Grit'] # # KeyError: 'Grit'
books_authors['non-existent-key']
# --------------------------------------------------------------------------- # KeyError Traceback (most recent call last) # <ipython-input-7-a3efd56f69e5> in <module> # ----> 1 books_authors['non-existent-key'] # # KeyError: 'non-existent-key'
那么,在 Python 中如何有效地处理 KeyError
呢?
接下来,我们将学习几种处理方法。
如何在 Python 中处理 KeyErrors
以下是处理 KeyError
的几种常用方法:
- 使用
if-else
条件语句 - 使用
try-except
语句块 - 使用字典的
.get()
方法
#1. 使用 If-Else 条件语句
使用 if-else
条件语句是处理 KeyError
的一种简单直接的方式。
if-else
语句的基本结构如下:
if condition: # 条件为真时执行 else: # 条件为假时执行
- 如果条件为
True
,则执行if
代码块中的语句。 - 如果条件为
False
,则执行else
代码块中的语句。
在这个示例中,条件用于检查指定的键是否存在于字典中。
如果键存在,in
运算符返回 True
,执行 if
代码块打印值。
key = 'The Happiness Equation' if key in books_authors: print(books_authors[key]) else: print('抱歉,该键不存在!') # 输出 # Neil Pasricha
如果键不存在,in
运算符返回 False
,执行 else
代码块,并打印提示信息。
key = 'non-existent-key' if key in books_authors: print(books_authors[key]) else: print('抱歉,该键不存在!') # 输出 # 抱歉,该键不存在!
#2. 使用 Try-Except 语句
另一种处理 KeyError
的常用方法是使用 try-except
语句。
代码示例:
key = 'non-existent-key' try: print(books_authors[key]) except KeyError: print('抱歉,该键不存在!')
try
代码块尝试获取指定键的值。- 如果键不存在,解释器会抛出
KeyError
异常,该异常会被except
代码块捕获并处理。
#3. 使用 .get() 方法
在 Python 中,可以使用内置的字典方法 .get()
来处理缺失的键。
.get()
方法的基本语法是:dict.get(key, default_value)
,其中 dict
是一个有效的 Python 字典对象。
– 如果键存在,.get()
方法返回对应的值。
– 否则,返回指定的默认值。
在这个示例中,我们定义了一个键的列表,并尝试从 books_authors
字典中检索它们对应的值。
我们使用 .get()
方法,并将 “不存在” 作为默认值。
keys = ['Grit','Hyperfocus','Make Time','Deep Work'] for key in keys: print(books_authors.get(key,'不存在'))
在上述代码中:
- 对于
books_authors
字典中存在的键,.get()
方法返回相应的值。 - 当键不存在时,如 “Grit” 和 “Make Time”,
.get()
方法返回默认值 “不存在”。
# 输出 # 不存在 # Chris Bailey # 不存在 # Cal Newport
以上方法都可以帮助我们处理 KeyError
,但它们都相对繁琐,需要显式地处理缺失的键。通过使用 defaultdict
,我们可以简化这一过程。
Python 中的 defaultdict
defaultdict
是 dict
类的子类,继承了 Python 字典的所有行为,并能原生处理缺失的键。
defaultdict
是一种容器数据类型,内置于 Python 标准库的 collections
模块中。
因此,你需要从 collections
模块导入 defaultdict
:
from collections import defaultdict
使用 defaultdict
的一般语法是:
defaultdict(default_factory)
你可以将 int
、float
或 list
等可调用对象指定为 default_factory
属性。如果没有为 default_factory
提供值,则默认为 None
。
当尝试访问字典中不存在的键时,会触发 __missing__()
方法,它会根据 default_factory
推断一个默认值并返回。
总结一下:
- 在 Python 中,当键不存在时,
defaultdict
返回一个默认值。 - 它还会将键值对(键,默认值)添加到字典中,之后你可以修改这个值。
Python 默认字典示例
接下来,我们将通过几个示例来了解 Python defaultdict
的工作原理。
Python 中具有默认整数值的 defaultdict
首先,从 collections
模块导入 defaultdict
。
from collections import defaultdict import random
创建一个 defaultdict
实例 prices
。
prices = defaultdict(int)
我们使用水果列表中的项目作为键来填充 prices
字典。从 price_list
中随机采样值作为对应的值。
price_list = [10,23,12,19,5] fruits = ['apple','strawberry','pomegranate','blueberry'] for fruit in fruits: prices[fruit] = random.choice(price_list)
让我们看一下 prices
defaultdict
中的键值对。
print(prices.items())
# dict_items([('apple', 12), ('blueberry', 19), ('pomegranate', 5), ('strawberry', 10)])
与普通的 Python 字典一样,你可以通过键访问 prices
defaultdict
的值:
prices['apple'] # 23
现在,让我们尝试访问一个不存在的水果的价格,例如 “orange”。我们看到它返回默认值零。
prices['orange'] # 0
如果我们打印字典,我们会看到添加了一个新键 “orange”,默认整数值为零。
print(prices.items())
# dict_items([('apple', 12), ('blueberry', 19), ('pomegranate', 5), ('strawberry', 10), ('orange', 0)])
Python 中以列表为默认值的 defaultdict
让我们将 students_majors
定义为以列表为默认值的 defaultdict
。专业的名字是键,值是攻读该专业的学生列表,如数学、经济学、计算机科学等。
from collections import defaultdict students_majors = defaultdict(list)
如果我们尝试访问 ‘Economics’ 对应的学生列表,defaultdict
返回一个空列表;不会有 KeyError
!
students_majors['Economics'] # []
现在我们有一个映射到 “Economics” 专业的空列表。 我们可以使用列表方法 .append()
向列表中添加元素。
students_majors['Economics'].append('Alex')
在 students_majors
defaultdict
中,为 “Economics” 专业创建了一个条目。
print(students_majors)
# defaultdict(<class 'list'>, {'Economics': ['Alex']})
可以向经济学专业添加更多学生,或者添加新的专业!
students_majors['Economics'].append('Bob') students_majors['Math'].append('Laura') print(students_majors)
# defaultdict(<class 'list'>, {'Economics': ['Alex', 'Bob'], 'Math': ['Laura']})
总结
希望本教程能帮助你理解如何在 Python 中使用 defaultdict
。在学习完本教程的代码示例后,你可以在项目中尝试使用 defaultdict
作为首选数据结构。
本教程的核心知识点总结如下:
- 在使用 Python 字典时,你可能会遇到
KeyError
。 - 可以使用条件语句、
try-except
语句块或.get()
方法处理此类错误。collections
模块中的defaultdict
可以简化KeyError
的处理。 - 使用
defaultdict(default_factory)
可以创建一个defaultdict
,其中default_factory
是一个有效的可调用对象。 - 当键在
defaultdict
中不存在时,默认值(从default_factory
推断)和键会被添加到defaultdict
中。
接下来,请查阅有关 Python 映射函数的教程。