摘要:如果两个对象是相同的,那么它们的散列值一定是相同的。也就是说,一个可散列对象必须同时满足以下三个条件支持方法,并且通过方法所获得的散列值是不变的支持通过方法来判断两个对象的值是否相等若,则必有。
字典
dict类型是python语言的基石,所以python对于dict类型实现了高度优化,而 散列表 则是字典类型性能突出的根本原因。
什么是可散列的数据类型定义:如果一个对象是可散列的,那么在这个对象的生命周期中,它的散列值是始终不变的,而且这个对象必定实现__hash__()方法。 另外,可散列对象还必须实现 __eq__()方法,这样才能保证两个相同类型的对象可以进行比较。如果两个对象是相同的,那么它们的散列值一定是相同的。
也就是说,一个可散列对象必须同时满足以下三个条件:
支持hash()方法,并且通过__hash__()方法所获得的散列值是不变的;
支持通过__eq__()方法来判断两个对象的值是否相等;
若 a==b,则必有 hash(a) == hash(b)。
原子不可变数据类型(str、bytes和数值类型)都是可散列类型;
frozenset类型也是可散列的;
当一个元组中所包含的值都是可散列的,该元组才是可散列的。
下例展示了创建字典的不同方式
>>> d1 = dict(one=1, two=2, three=3) >>> d2 = {"one":1, "two":2, "three":3} >>> d3 = dict(zip(["one", "two", "three"], [1,2,3])) >>> d4 = dict([("two", 2), ("one", 1), ("three", 3)]) >>> d5 = dict({"one":1, "two":2, "three":3}) >>> d1 == d2 == d3 == d4 == d5 True处理找不到的键
假设有一个字典dict,当程序试图查找一个不存在的键值 dict[k] 时,会抛出一个异常KeyError,这个行为复合python所信奉的“快速失败”哲学。当然,我们可以采用dict.get(k, default)来代替dict[k],当找不到键k时,返回默认值default,但是,这并不是一个高效的方式,也不是一个可取的方法。
1. setdefault方法下面是一个案例:
dict_demo = {} print(dict_demo) key = "name" dict_demo.get(key) dict_demo.setdefault(key, []) print(dict_demo) dict_demo.setdefault("pass", "123456") print(dict_demo)
运行结果如下:
{} {"name": []} {"name": [], "pass": "123456"}
代码中第一个 setdefault 中未找到 key,于是把一个空列表赋值到该键值
第二个 setdefault 未找到键"pass",将一个字符串赋值给该键
经过两个setdefault之后,该字典含有两个键值对,该方法主要用于对字典进行更新
2.defaultdict 处理空缺键的一个选择在用户创建defaultdict对象时,需要给它配置一个为找不到的键创造默认值的方法
具体而言,就是在实例化一个defaultdict对象时,需要给构造方法赋予一个可调用对象,这个可调用对象在__getitem__碰到找不到的键时,让__getitem__返回一个默认值。
key = "name" dict_demo2 = collections.defaultdict(list) print(dict_demo2) dict_demo2[key].append((1,2)) print(dict_demo2) dict_demo2["pass"] print(dict_demo2)
运行结果:
defaultdict(, {}) defaultdict( , {"name": [(1, 2)]}) defaultdict( , {"name": [(1, 2)], "pass": []})
dict_demo2一开始是一个空字典,不存在任何键值,当运行dict_demo2[key]时,其中包含一下三个步骤:
(1) 调用list()创建一个新列表
(2) 把这个新列表作为值,key作为键,放入dd中
(3) 返回这个列表的引用(这也是能够进行append操作的原因)
如果在键值不确定的情况下可以考虑使用defaultdict
3 特殊方法__missing__所有映射类型在处理找不到的键时,都会牵扯__missing__方法,当__getitem__操作找不到键值时,就会调用__missing__方法,而不是直接抛出异常。
__missing__方法只会被__getitem__方法调用
class StrKeyDict0(dict):
def __missing__(self, key): if isinstance(key, str): raise KeyError(key) return self[str(key)] def get(self, key, default=None): try: return self[key] except KeyError: return default def __contains__(self, key): return key in self.keys() or str(key) in self.keys()
if name == "__main__":
d = StrKeyDict0([("2", "two"), ("4", "four")]) print(d["2"]) print(d[4]) try: print(d[1]) except KeyError: print("keyerror") print(d.get("2")) print(d.get(4)) try: print(d.get(1, "N/A")) except KeyError: print("keyerror") print(2 in d) print(4 in d)
运行结果:
two four keyerror two four N/A True True
__missing__方法中将键key转化为str类型后再次尝试获取字典d中相应的键值
所以可以看到,即便字典中没有 4 这个键,但是依然能够正确获取其在字典中相应的值,但是由于字典中不存在 1 或 "1" 这样的键,所以无法获取d[1]
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/42242.html
摘要:常量的值近似为。在后传入一个整数可以保证该域至少有这么多的宽度表示浮点数保留位小数常量的值近似为。 1. 数字 类型 int, float, bool, complex type() 查看变量类型 isinstance(a, int) 查看变量类型 showImg(https://segmentfault.com/img/remote/1460000016789047); 运算符 ...
摘要:第六章抽象本章会介绍如何将语句组织成函数。关键字参数和默认值目前为止,我们使用的参数都是位置参数,因为它们的位置很重要,事实上比它们的名字更重要。参数前的星号将所有值放置在同一个元祖中。函数内的变量被称为局部变量。 第六章:抽象 本章会介绍如何将语句组织成函数。还会详细介绍参数(parameter)和作用域(scope)的概念,以及递归的概念及其在程序中的用途。 懒惰即美德 斐波那契数...
摘要:的基本数据类型中的变量不需要声明。在里,只有一种整数类型,表示为长整型,没有中的。字符串的截取的语法格式如下变量头下标尾下标索引值以为开始值,为从末尾的开始位置。列表列表是中使用最频繁的数据类型。注意构造包含或个元素的元组的特殊语法规则。 1、python3的基本数据类型 Python 中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。在 Python 中,...
摘要:基本数据类型基本数据类型比较简单,通过以下例子演示运行结果如下通用序列操作索引通过索引获取序列的单个元素,也可以使用负数索引。设置参数步长,负数步长表示从右侧开始提取元素。注意相同类型的序列才可以进行连接操作。 showImg(https://segmentfault.com/img/bV09Mw?w=805&h=327); 0. 基本数据类型 基本数据类型比较简单,通过以下例子演示:...
阅读 838·2021-11-18 10:07
阅读 2355·2021-10-14 09:42
阅读 5322·2021-09-22 15:45
阅读 585·2021-09-03 10:29
阅读 3463·2021-08-31 14:28
阅读 1874·2019-08-30 15:56
阅读 3040·2019-08-30 15:54
阅读 995·2019-08-29 11:32