type
status
date
slug
summary
tags
category
icon
password
Email
字典
创建字典的方式
字典由
关键字
和 值
组成。由于关键字需要是索引,因此关键字必须是 不可变类型。通常为字符串或者数值,不能用列表做关键字。
字典的创建形式:
{关键字: 值}
中间使用:分割字典的关键字可以组成列表:
list
形成列表, sorted
对列表排序使用
dict
直接创建字典:dict中形成字典的大括号既可以使用
{}
也可以使用 []
,但是键值对必须是 ()
使用字典推导式创建字典:以任意键值对作为元素的可迭代对象中构建出字典。
dict
创建关键字都是字符串类型的字典:字面语法与构造方法:
setdefault
一个统计文本中所有单词出现的行列坐标的程序:
defaultdict
提供了一个为找不到的键创建默认值的方法:
如果index没有word的值,则会调用
default_factory
为查询不到的键创建一个值,这个值在这里是一个 空列表
,然后赋值给 words_dict[word],并且是一个引用,然后可以执行 append的操作。如果在创建 defaultdict 的时候没有指定 default_factory,查询不存在的键会触发 KeyError
__missing__方法
当对象找不到某个键的时候,可以通过这个方法自定义会发生什么。
对于我们实现自定义的字典,并且重写特定方法时,这个方法很有用。
尤其是用于
UserDict
中(下文讲解)字典的变种
collections.OrderedDict
添加键的时候会保持顺序,保持迭代顺序也始终是一致的。它具有
popitem
方法,其默认删除最后一个元素,如果设置 last=False
,则删除的就是第一个元素,并且返回这个值collections.ChainMap
可以把多个映射集合到一个视图里面在进行键查找操作的时候,这些对象会被当作一个整体被逐个查找,直到键被找到为止
collections.Counter
可以产生一个具有计数功能的映射,使用
update
可以进行更新collections.UserDict
把Dict用纯python纯写的,UserDict非常适合于继承。可以说它封装了字典对象,简化了字典子类化
它具有一个
data
属性,其中存储着 Dict真正的数据,这才是一个真正的字典。子类化UserDict
如果要创建自定义类型,则使用 UserDict 比使用普通的dict要方便的多。
创建一个可以自动将非字符串类型的键 转换为字符串类型并且进行查询,修改,删除的字典:
字典的构造过程:
- 首先通过构造函数进入
__init__
函数进行对象的构造,然后如果传入的dict不是空,则会进入update
函数进行插入键值对.
- 进入到
update
函数后,首先检查传入的参数是否是Mapping
映射类型,如果是则进行下一步。
- 然后
键值对
的插入操作,进入到__setitem__
函数中,我们重写这个函数,把键全部改为str类型,因此我们无论输入的键是什么类型,都会是str类型
字典的 in 操作:
in
操作会执行__contains__
函数,因此在此函数中我们直接把key值变为str类型,然后使用内置的 in 进行查询
字典的查询操作:
- 通过 sdict[i] 查询一个值,首先会进入
__getitem__
函数中,如果查询的键不存在,则会进入到一个__missing__
函数中,该函数用来进行查询不到键时该如何操作。
- 在此函数中,我们判断如果这个不存在的键是str类型,则意味着这个键是合法的,但是却没有值,因此它确实没有这个值,抛出
KeyError
异常。
- 如果我们的键是int类型,但是str(int)的键却是有值的,因此将key 转换为
str(key)
然后再次进入到__getitem__
中查询类型为str的键是否存在值,如果没有,则执行 2操作,抛出异常,然后退出。如果有值,则返回。
不可变映射类型
字典都是可变的,有没有一种字典是不可变的呢?
types 模块的
MappingProxyType
提供了这样一种方法。在MappingProxyType对象中执行更改操作会出错,因为它返回的只是一个只读视图
但是在源对象中更改是允许的。对原映射做出了改动,我们通过这个视图可以观察到。
字典的实现
dict内部使用
散列表
实现使用散列表会给字典带来哪些优势和限制呢?
- 字典的键必须是可散列的。
- 字典在内存上开销巨大
- 键查询很快
- 键的次序取决于添加次序
- 往字典里添加新键可能会改变已有键的顺序
什么是可散列的?一个可散列的对象必须满足以下的条件:
- 必须支持 hash() 函数,并且通过 hash() 函数得到的散列值是不可变的。
- 支持通过 __ eq__来检测相等性
- 如果 a==b ,则 hash(a)==hash(b) 必须成立
- 所有用户自定义的对象都是可散列的,因为他们的散列值是通过id来获得的,并且他们都是不相等的。
- 作者:Yuleo
- 链接:https://www.helloylh.com/article/python2
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。