python 两个列表相互映射_流畅的Python笔记(第3章):字典和集合

本章主要讨论字典和集合相关内容,dict类型是Python语言的基石。模块的命名空间、实例的属性和函数的关键字参数中都可以看到字典的身影。

泛映射类型

collections.abc模块中有Mapping和MutableMapping两个抽象基类,它们的作用是为dict和其他类型的类型定义形式接口。

python 两个列表相互映射_流畅的Python笔记(第3章):字典和集合_第1张图片

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

什么是可散列的数据类型

如果一个对象是可散列的,那么在这个对象的声明周期中,它的散列值是不变的,而且这个对象需要实现__hash__特殊方法。另外可散列对象还要有__eq__方法,这样才能跟其他键作比较。如果两个可散列对象是相等的,那么他们的散列值一定是一样的。

原子不可变数据类型(str、bytes和数值类型)都是可散列类型,frozenst也是可散列的,因为根据其定义,frozenset里只能容纳可散列类型。元组的话,只有当一个元组包含的所有元素都是可散列类型的情况下,它才是可散列的。

字典推导

常见的映射方法

具体了解可查阅本书3.3节

用setdefault处理找不到的键

当字典d[k]不能找到正确的键的时候,Python会抛出异常,这个行为符合Python所信奉的"快速失败"哲学。

>>> a = {}
>>> a.setdefault('dw', []).append(1)
>>> a
{'dw': [1]}

通过在子类中定义__missing__方法,也可以处理键不存在的情况。

字典的变种

collections.OrderedDict

这个类型在添加键的时候会保持顺序,因此迭代次序总是一致的。

collections.ChainMap

这个类型可以容纳数个不同的映射对象,然后在进行建查找操作的时候,这些对象会被当做一个整体被逐个查找,直到键被找到为止。

collections.Counter

这个映射类型会给键准备一个整数计数器,每次更新一个键的时候都会增加这个计算器。

collections.UserDict

这个类其实就是把标准dict用纯Python又实现了一遍。UserDict是让用户继承写子类的。

子类化UserDict

UserDict并不是dict的子类,它有一个叫做data的属性,是dict的实例,这个属性实际上是UserDict最终存储数据的地方。

不可变映射类型

标准库里所有的映射类型都是可变的,但有时候你会有这样的需求,比如不能让用户错误地修改某个映射。

从Python3.3开始,types模块中引入了一个封装类名叫MappingProxyType。如果给这个类一个映射,它会返回一个只读的映射视图。 示例如下:

>>> d = {'dw': 1}
>>> a = MappingProxyType(d)
>>> a
mappingproxy({'dw': 1})
>>> a['dw'] = 2
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'mappingproxy' object does not support item assignment

集合论

"集"这个概念在Python中算是比较年轻的,同时它的使用率也比较低。set和它的不可变姊妹类型frozenset直到Python2.3才首次以模块的形式出现,然后在Python2.6中它们升级为内置类型。

集合的本质是许多唯一对象的聚集。因此集合可以用于去重:

>>> a = ['a', 'a', 'b']
>>> set(a)
{'a', 'b'}
>>> list(set(a))
['a', 'b']

集合中的元素必须是可散列的,set类型本身是不可散列的,但是frozenset可以。

集合的字面量

除空集以外,集合的字面量:{1}、{1, 2}等等,看起来跟它的数学形式一模一样。如果是空集,那么必须写成set()形态。

集合的推导

示例代码:

>>> {i for i in 'abc'}
{'c', 'a', 'b'}

集合的操作

python 两个列表相互映射_流畅的Python笔记(第3章):字典和集合_第2张图片

上图列出了可变和不可变集合所拥有的方法的概况,其中不少是运算符重载的方法。

dict的实现及其导致的结果

  • 键必须是可散列的。
  • 字典在内存上开销巨大。 由于字典使用了散列表,而散列表又必须是稀疏的,这导致它在空间上的效率低下。
  • 键查询很快。
  • 键的次序取决于添加顺序。
  • 往字典里添加新键可能会改变已有键的顺序。

set的实现及其导致的结果

  • 集合里的元素必须是可散列的。
  • 集合很消耗内存。
  • 可以很高效地判断元素是否存在于某个集合。
  • 元素的次序取决于被添加到集合里的次序。
  • 往集合里添加元素,可能会改变集合里已有元素的次序。

你可能感兴趣的:(python,两个列表相互映射)