第3章 字典与集合
类和实例属性、模块命名空间、函数关键字参数等核心Python构造在内存中都是以字典形式表示。字典和集合的底层实现基于哈希表,这是它们高性能的关键。
字典现代操作
字典推导式
字典推导式通过任意可迭代对象中提取键值对来构建dict实例
# 示例3-1: 字典推导式
dial_codes = [
(880, 'Bangladesh'),
(55, 'Brazil'),
(86, 'China'),
(91, 'India'),
(62, 'Indonesia'),
(81, 'Japan'),
(234, 'Nigeria'),
(92, 'Pakistan'),
(7, 'Russia'),
(1, 'United States'),
]
# 交换键值对:country作为键,code作为值
country_dial = {
country: code for code, country in dial_codes}
# 按国家名称排序,交换键值对,将值转为大写,并筛选出code < 70的项
filtered_codes = {
code: country.upper()
for country, code in sorted(country_dial.items())
if code < 70
}
print("country_dial:", country_dial)
print("filtered_codes:", filtered_codes)
解包映射
# 在函数调用中对多个参数应用**解包
def dump(**kwargs):
return kwargs
# 此时所有的键必须是唯一的字符串 在函数调用中,关键字参数本质上是命名参数
# 在 dump(**{'x': 1}, **{'x': 2})时会报错
# TypeError: dump() got multiple values for keyword argument 'x'
result1 = dump(**{
'x': 1}, y=2, **{
'z': 3})
print("dump result:", result1) # 输出: {'x': 1, 'y': 2, 'z': 3}
# 进行字面量解包 此时允许重复的键 但后面的键会覆盖前面的键
# **解包可以多次使用
result2 = {
'a': 0, **{
'x': 1}, 'y': 2, **{
'z': 3, 'x': 4}}
print("merged dict:", result2) # 输出: {'a': 0, 'x': 4, 'y': 2, 'z': 3}
合并映射
# 使用|操作符合并映射(创建新映射)
d1 = {
'a': 1, 'b': 3}
d2 = {
'a': 2, 'b': 4, 'c': 6}
merged = d1 | d2
print("Merged with |:", merged) # 输出: {'a': 2, 'b': 4, 'c': 6}
# 使用|=原地更新现有映射
d1 |= d2
print("d1 after |=:", d1) # 输出: {'a': 2, 'b': 4, 'c': 6}
# 通常,新映射的类型与左操作数的类型相同,但涉及用户自定义类型时可能根据操作符重载规则采用右操作数的类型
# 此处涉及python重载类型的具体实现 以及类__or__的实现
模式匹配
match/case语句支持映射对象作为匹配主体,映射模式看起来像字典字面量,但可以匹配任何collections.abc.Mapping的具体子类或者虚拟子类。
def get_creators(record):
"""从媒体记录中提取创作者姓名"""
match record:
case {
'type': 'book', 'api': 2, 'authors': [*names]}:
return names
case {
'type': 'book', 'api': 1, 'author': name}:
return [name]
# 不符合上述匹配的type模式都是不合法的 报错
case {
'type': 'book'}:
raise ValueError(f"Invalid 'book' record: {
record!r}")
case {
'type': 'movie', 'director': name}:
return [name]
case _:
raise ValueError(f'Invalid record: {
record!r}')
# 测试示例
if __name__ == "__main__":
# 测试书籍记录 (api=1)
b1 = dict(api=1, author='Douglas Hofstadter',
type='book', title='Gödel, Escher, Bach')
print("Book 1 creators:", get_creators(b1)) # 输出: ['Douglas Hofstadter']
# 测试书籍记录 (api=2)
from collections import OrderedDict
b2 = OrderedDict(api=2, type='book',
title='Python in a Nutshell',
authors='Martelli Ravenscroft Holden'.split())
print("Book 2 creators:", get_creators(b2)) # 输出: ['Martelli', 'Ravenscroft', 'Holden']
# 测试无效书籍记录
try:
get_creators({
'type': 'book', 'pages': 770})
except ValueError as e:
print("Error:", str(e))
# 测试非字典记录
try:
get_creators('Spam, spam, spam')
except ValueError as e:
print("Error:", str(e))
# 测试捕获额外键值对
food = dict(category='ice cream', flavor='vanilla', cost=199)
match food:
case {
'category': 'ice cream', **details}:
print(f"Ice cream details: {
details
Python字典与集合详解

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



