Python--字典

键的次序取决于添加顺序,但是往字典里添加新键可能会改变已有键的顺序
无论何时往字典里添加新的键,Python 解释器都可能做出为字典扩容的决定。扩容导致的结果就是要新建一个更大的散列表,并把字典里已有的元素添加到新表里。这个过程中可能会发生新的散列冲突,导致新散列表中键的次序变化。要注意的是,上面提到的这些变化是否会发生以及如何发生,都依赖于字典背后的具体实现。
 
如果你在迭代一个字典的所有键的过程中同时对字典进行修改,那么这个循环很有可能会跳过一些键——甚至是跳过那些字典中已经有的键。
由此可知,不要对字典同时进行迭代和修改。如果想扫描并修改一个字典,最好分成两步来进行:
  首先对字典迭代,以得出需要添加的内容,把这些内容放在一个新字典里;
  迭代结束之后再对原有字典进行更新。
 
1.dict其它方法
d.__contains__(k)    #检查 k 是否在 d 中
d.__setitem__(k,v)   #实现 d[k] = v 操作,把 k 对应的值设为v
d.default_factory   #在 __missing__ 函数中被调用的函数,用以给未找到的元素设置值*
d.__delitem__(k)
del d[k]     #移除键为 k 的元素
d.__getitem__(k)   #让字典 d 能用 d[k] 的形式返回键 k 对应的值
d.__iter__()    #获取键的迭代器
d.__len__()     #可以用 len(d) 的形式得到字典里键值对的数量
d.__missing__(k)   #当 __getitem__ 找不到对应键的时候,这个方法会被调用
d.move_to_end(k,[last])把键为 k 的元素移动到最靠前或者最靠后的位置(last的默认值是 True)
d.__reversed__()    #返回倒序的键的迭代器
d.__setitem__(k,v)   #实现 d[k] = v 操作,把 k 对应的值设为v

 

2.键查询

有时候为了方便起见,就算某个键在映射里不存在,我们也希望能得到一个默认值。
有两个途径,一个是通过 defaultdict 这个类型而不是普通的 dict,另一个是给自己定义一个 dict 的子类,然后在子类中实现__missing__ 方法。
如果有一个类继承了 dict,然后这个继承类提供了__missing__ 方法,那么在 __getitem__ 碰到找不到的键的时候,Python 就会自动调用它,而不是抛出一个 KeyError 异常。
 
3.字典的变种
collections.OrderedDict
  这个类型在添加键的时候会保持顺序,因此键的迭代次序总是一致的。OrderedDict 的 popitem 方法默认删除并返回的是字典里的最后一个元素。
 
collections.ChainMap
  该类型可以容纳数个不同的映射对象,然后在进行键查找操作的时候,这些对象会被
当作一个整体被逐个查找,直到键被找到为止。
import builtins
pylookup = ChainMap(locals(), globals(), vars(builtins))
 
collections.Counter
  这个映射类型会给键准备一个整数计数器。每次更新一个键的时候都会增加这个计数器。
计算单词中各个字母出现的次数:
ct = collections.Counter('abracadabra')
print(ct)     #Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
ct.update('aaaaazzz')
print(ct)     #Counter({'a': 10, 'z': 3, 'b': 2, 'r': 2, 'c': 1, 'd': 1})
l=ct.most_common(2)
print(l)      #[('a', 10), ('z', 3)]
 
colllections.UserDict
  UserDict 是让用户继承写子类的。
值得注意的地方是,UserDict 并不是 dict 的子类,但是 UserDict 有一个叫作 data 的属性,是 dict 的实例,这个属性实际上是 UserDict 最终存储数据的地方。
下面StrKeyDict 都会把非字符串的键转换为字符串
import collections
class StrKeyDict(collections.UserDict): 
    def __missing__(self, key): 
        if isinstance(key, str):
            raise KeyError(key)
        return self[str(key)]
    def __contains__(self, key):
        return str(key) in self.data 
    def __setitem__(self, key, item):
        self.data[str(key)] = item 

 

posted @ 2020-12-05 16:06  盲仔不瞎忙  阅读(55)  评论(0编辑  收藏  举报