Python 字典

一个有意思的事实是,Python 的字典的 .keys().items() 方法返回的是两个内置的视图对象,且无法被外部直接拿去使用(但可以获取该实例)。它们属于字典视图(在 Python 2 中是以列表形式显现的,因为无意义占用内存,所以在 Python 3 中被改为了现在的视图)。

当然,因为字典使用的是哈希表,所以其查询速度比序列更快(但是占用内存也更大,因为哈希表需要保留约 1/3 的空间)。

值得一提的是,创建字典字面量 {a:1, b:2} 比使用构造函数 dict(a=1, b=2) 效率更高(书中写的是 set,不过我想字典应该也差不多)。而且在创建一个类实例时,内部也会构建一个哈希表,因此应当在 __init__ 中来创建字典实例,这样字典与实例就是共用的同一个哈希表(在方法中创建会新建一个哈希表),这样可以节省内存(不过好像一个进程只有效一次?这部分我没太看懂)。

Python 集合

很有意思的是,Python 的 set 实现了数学意义上对集合的所有使用方法,包括交集、并集、差集、对称差集等,且 set 里面的内容必须是可哈希的(但 set 本身不可哈希,因此 set 无法嵌套,而 frozenset 是可哈希的)。不过鉴于 Python 每次创建进程时哈希码都会有所不同,因此 set 里面的元素是完全无序的。

如果想消除一个序列中的重复项同时保持顺序,可以使用 dict.fromkeys(l),其中 l 为序列。此方法会把 l 映射为字典的 .keys() 视图,该视图会像集合一样删除重复项,但重要的是它能保留顺序(Python 3.7+ 中字典保持插入顺序),因此你可以把它转为序列重新使用。当然,鉴于 .keys().items() 的这种特性,它们是可以和 set 进行集合运算的!