python 字典和集合 简介

本文详细探讨了Python中的字典数据结构,包括其广泛应用、Python对字典的优化以及散列表在字典和集合中的核心作用。还介绍了Mapping和MutableMapping抽象基类,以及字典的构造方法、映射方法和可散列类型的要求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

字典这个数据结构活跃在所有 Python 程序的背后,即便你的源码里并没有直接用到它。

dict 类型不但在各种程序里广泛使用,它也是 Python 语言的基石模块的命名空间实例的属性函数的关键字参数中都可以看到字典的身影。跟它有关的内置函数都在__builtins__.__dict__ 模块中。

正是因为字典至关重要,Python 对它的实现做了高度优化,而散列表则是字典类型性能出众的根本原因。

集合(set)的实现其实也依赖于散列表。反过来说,想要进一步理解集合和字典,就得先理解散列表的原理。

  • 泛映射类型
    collections.abc 模块中有 Mapping 和 MutableMapping 这两个抽象基类,它们的作用是为dict 和其他类似的类型定义形式接口(在 Python 2.6Python 3.2 的版本中,这些类还不属于 collections.abc 模块,而是隶属于 collections 模块)
    在这里插入图片描述
    然而,非抽象映射类型一般不会直接继承这些抽象基类,它们会直接对 dict 或是collections.User.Dict 进行扩展。这些抽象基类的主要作用是作为形式化的文档,它们定义了构建一个映射类型所需要的最基本的接口。然后它们还可以跟 isinstance 一起被用来
    判定某个数据是不是广义上的映射类型。
from collections import abc

print(isinstance({}, abc.Mapping))
# True

这里用 isinstance 而不是 type 来检查某个参数是否为 dict 类型,因为这个参数有可能不是 dict,而是一个比较另类的映射类型。

标准库里的所有映射类型都是利用 dict 来实现的,因此它们有个共同的限制,即只有可散列数据类型才能用作这些映射里的(只有键有这个要求,值并不需要是可散列的数据类型)

  • 什么是可散列的数据类型
    在 Python 词汇表(https://docs.python.org/3/glossary.html#term-hashable)中,关于可散列类型的定义有这样一段话:
    如果一个对象是可散列的,那么在这个对象的生命周期中,它的散列值不变的,而且这个对象需要实现 __hash__() 方法。另外可散列对象还要有 __qe__()方法,这样才能跟其他键做比较。如果两个可散列对象是相等的,那么它们的散列值一定是一样的……
    原子不可变数据类型(strbytes数值类型)都是可散列类型,frozenset 也是可散列的,因为根据其定义,frozenset 里只能容纳可散列类型。元组的话,只有当一个元组包含所有元素都是可散列类型的情况下,它才是可散列的。来看下面的元组 tt、
    tl 和 tf:
    在这里插入图片描述
    Python 词汇表(https://docs.python.org/3/glossary.html#term-hashable)里还在说“Python所有的不可变
    型都是可散列的”。这个说法其实是不准确的,比如虽然元组本身是不可变序列,它里面的元素可能其他可变类型的引用

根据这些定义,字典提供了很多种构造方法“Built-in Types”(https://docs.python.org/3/library/stdtypes.html#mapping-types-dict)示例说明

a = dict(one=1, two=2, three=3)
b = {'one': 1, 'two': 2, 'three': 3}
c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))
d = dict([('two', 2), ('one', 1), ('three', 3)])
e = dict({'three': 3, 'one': 1, 'two': 2})
print(a == b == c == d == e)
# True

除了这些字面句法和灵活的构造方法之外,字典推导dict comprehension)也可以用来建造新 dict

  • 常见的映射方法
    映射类型的方法其实很丰富。下表为我们展示了 dictdefaultdictOrderedDict 的常见方法,后面两个数据类型是 dict 的变种,位于 collections 模块内。
    dictcollections.defaultdictcollections.OrderedDict这三种映射类型的方法列表(依然省略了继承自object的常见方法);可选参数以[…]表示
    在这里插入图片描述
    在这里插入图片描述
    default_factory 并不是一个方法,而是一个可调用对象(callable),它的值在 defaultdict 初始化的时候由用户设定。
    OrderedDict.popitem() 会移除字典里最先插入的元素(先进先出);同时这个方法还有一个可选的 last参数,若为真,则会移除最后插入的元素(后进先出)。

上面的表格中,update 方法处理参数 m 的方式,是典型的“鸭子类型”。函数首先检查 m是否有 keys 方法,如果有,那么 update 函数就把它当作映射对象来处理。否则,函数会退一步,转而把 m 当作包含了键值对 (key, value) 元素的迭代器。Python 里大多数映射类型的构造方法都采用了类似的逻辑,因此你既可以用一个映射对象来新建一个映射对象,也可以用包含 (key, value) 元素的可迭代对象来初始化一个映射对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值