字典是我们经常用到一种数据类型,而且也很方便。虽然用得很多,但是我对它的操作也仅限于取值,赋值,创建新字典。
首先出现是两个抽象基类,为dict
和其他泛映射类型定义了接口。然后是字典推导,这个跟之前的列表推导差不多,不难。创建字典的方法也有很多,之前常用的也只是两三种——直接把字典赋值给一个对象、使用dict()
把其他序列转为字典。
然后是字典的一个之前没用过的方法setdefault
,它用来处理找不到的键。而另一个相似的方法get
我也不怎么用,都是用d[x]
这样的形式。
另一类型的字典,collections 模块中的 defaultdict,可以替代上面的setdefault
方法。创建时提供一个对象,在之后取某个键,但不存在时调用__getitem__
方法返回某个默认值。
后面的,依旧没看完。明天看吧。
这次遇到了特殊方法__missing__
,当指定键不存在的时它就会被调用。所有映射类型都一样,都是在找不到指定键时会调用它。但要注意的是,__missing__
只会被__getitem__
调用。
collections 模块中还有其他的映射类型,一个是有序字典 OrderdDict,popitem
方法也有不同,它默认删除并返回最后一个元素。ChainMap 对象容纳多个映射对象,然后对其进行查找的时候,它被当作一个整体进行查找。Counter 对象为键这样一个整数计数器,「每次更新一个键的时候都会增加这个计数器」。书上一个例子是用来计算字符串中每个字符出现的次数。
UserDict 是用纯 Python 把标准 dict 实现了一遍,由于用户继承写子类。它继承自超类 MutableMapping。
关于字典,还有就是不可变映射类型了。types 模块中的 MappingProxyType 就是这样。它返回的是视图,用户不能对视图进行修改。但它是动态的,对原映射的修改它可以看到。
之后就是集合了。这个数据类型也经常用到,它支持集合推导,跟之前的字典推导、列表推导差不多。它还有不可变的姊妹类型 frozenset。
在他们背后,底层实现是散列表。这使得他们的查找效率很高,受数据量影响很小。这是用空间换取的时间,而一开始空间不会很大,当数据量增大的时候,到一定程度,会把数据复制到新的更大的空间,所以集合的元素顺序不稳定。
在字典和集合中,除了标准的字典和集合,之前只用到了有序字典。而在合适的场合,标准类型之外的字典和集合会更适合。果然要多动手啊。