【python核心编程读书笔记】第7章--映射和集合
映射dictdict是python里面唯一的映射类型。
核心笔记:什么是哈希表?它们与字典的关系是什么?
序列类型用有序的数字键做索引将数据以数组的形式存储。一般,索引值与所存储的数据毫无关系。还可以用另一种方式来存储数据:基于某种相关值,比如说一个字符串。我们在日常生活中一直这么做。你把人们的电话号码按照他们的姓记录在电话簿上,你按照时间在日历或约会簿上添加事件,等等。在这些例子中,你的键(key)就是和数据项相关的值。 哈希表是一种数据结构:它按照我们所要求的去工作。哈希表中存储的每一条数据,叫做一个值(value),是根据与它相关的一个被称作为键(key)的数据项进行存储的。键和值合在一起被称为“键-值 对”(key-value pairs)。 哈希表的算法是获取键,对键执行一个叫做哈希函数的操作,并根据计算的结果,选择在数据结构的某个地址中来存储你的值。任何一个值存储的地址皆取决于它的键。正因为这种随意性,哈希表中的值是没有顺序的。你拥有的是一个无序的数据集。 你所能获得的有序集合只能是字典中的键的集合或者值的集合。 方法Keys() 或 values() 返回一个列表,该列表是可排序的。 你还可以用 items()方法得到包含键、值对的元组的列表来排序。由于字典本身是哈希的,所以是无序的。 哈希表一般有很好的性能, 因为用键查询相当快。
表 7.1 映射类型的相关函数
函数 操作
dict() 创建字典的工厂函数。如果提供了容器类 (container) , 就 用其中的条目填充字典,否则就创建一个空字典。
len(mapping) 返回映射的长度(键-值对的个数)
hash(obj) 返回 obj 的哈希值
由于keys必须是可哈希的,所以,如果使用自定义类型对象作为keys时,必须保证该类型执行hash(obj)返回整数且不报错。
表 7.2 字典类型方法
方法名字 操作
dict.clear() 删除字典中所有元素
dict.copy() 返回字典(浅复制)的一个副本
dict.fromkeys (seq,val=None)创建并返回一个新字典,以 seq 中的元素做该字典的键
val 做该字典中所有键对应的初始值(如果不提供此值,则默认为 None)
dict.get(key, default=None) 对字典 dict 中的键 key,返回它对应的值 value,如果字典中不存在此键
则返回 default 的值(注意,参数 default 的默认值为 None)
dict.has_key(key) 如果键(key)在字典中存在, 返回 True, 否则返回 False. 在 Python2.2版本
引入 in 和 not in 后,此方法几乎已废弃不用了,但仍提供一个可工作的接口。
dict.items() 返回一个包含字典中(键, 值)对元组的列表
dict.keys() 返回一个包含字典中键的列表
dict.iter() 方法 iteritems(), iterkeys(), itervalues()与它们对应的非迭代方法一样
不同的是它们返回一个迭代子,而不是一个列表。
dict.pop(key [, default]) 和方法 get()相似,如果字典中 key 键存在,删除并返回 dict
如果 key 键不存在,且没有给出 default 的值,引发 KeyError 异常。
dict.setdefault(key, default=None) 和方法 set()相似,如果字典中不存在 key 键,由 dict=default 为它赋值。
dict.update(dict2) 将字典 dict2 的键-值对添加到字典 dict
dict.values() 返回一个包含字典中所有值的列表
由于keys更多是参数而不是索引,所以dict是无序的。在 Python 2.4 版本以前, 你只能调用字典的 keys()方法获得键的列表, 然后调用列表的 sort()方法得到一个有序可遍历的列表。现在特别为迭代子设计了一个名为 sorted()的内建函数,它返回一个有序的迭代子 。
所有不可变的类型都是可哈希的, 因此它们都可以做为字典的键。 一个要说明的是问题是数字:值相等的数字表示相同的键。换句话来说,整型数字 1 和 浮点数 1.0 的哈希值是相同的,即它们是相同的键。
同时,也有一些可变对象(很少)是可哈希的,它们可以做字典的键,但很少见。举一个例子,一个实现了__hash__() 特殊方法的类。因为__hash__()方法返回一个整数,所以仍然是用不可变的值(做字典的键)。
集合sets
数学上, 把 set 称做由不同的元素组成的集合,集合(set)的成员通常被称做集合元素(set elements)。 Python 把这个概念引入到它的集合类型对象里。 集合对象是一组无序排列的可哈希的值。
集合(sets)有两种不同的类型,可变集合(set) 和 不可变集合(frozenset)。如你所想,对可变集合(set),你可以添加和删除元素,对 不可变集合(frozenset)则不允许这样做。请注意,可变集合(set)不是可哈希的,因此既不能用做字典的键也不能做其他集合中的元素。不可变集合(frozenset)则正好相反,即,他们有哈希值,能被用做字典的键或是作为集合中的一个成员。
set操作与数学符号的对应关系http://onexin.iyunv.com/source/plugin/onexin_bigdata/file:///C:Userssecond.second-PCAppDataRoamingTencentUsers22720660QQWinTempRichOle7]C`7]%9}`@IO$Z@8~U@K
与序列和映射不同,集合只能使用其工厂函数进行创建。set() 和 frozenset()
集合可以使用add,remove进行元素增删。
如果左右两个操作数的类型相同,既都是可变集合或不可变集合, 则所产生的结果类型是相同的,但如果左右两个操作数的类型不相同(左操作数是 set,右操作数是 frozenset,或相反情况),则所产生的结果类型与左操作数的类型相同。还要注意,加号不是集合类型的运算符 。
(Union) Update ( |= )
这个更新方法从已存在的集合中添加(可能多个)成员,此方法和 update()等价
保留/交集更新( &= )
保留(或交集更新)操作保留与其他集合的共有成员。此方法和 intersection_update()等价
差更新 ( –= )
对集合 s 和 t 进行差更新操作 s-=t,差更新操作会返回一个集合,该集合中的成员是集合 s 去除掉集合 t 中元素后剩余的元素。此方法和 difference_update()等价
对称差分更新( ^= )
对集合s和t 进行对称差分更新操作(s^=t),对称差分更新操作会返回一个集合,该集合中的成员仅是原集合 s 或仅是另一集合 t 中的成员。此方法和 symmetric_difference_update()等价 。
表 7.4 集合类型方法
方法名称 操作
s.issubset(t) 如果s是t 的子集,则返回 True,否则返回 False
s.issuperset(t) 如果t是s 的超集,则返回 True,否则返回 False
s.union(t) 返回一个新集合,该集合是s和t 的并集
s.intersection(t) 返回一个新集合,该集合是s和t 的交集
s.difference(t) 返回一个新集合,该集合是 s 的成员,但不是 t 的成员
s.symmetric_difference(t) 返回一个新集合,该集合是 s 或 t 的成员,但不是s和t共有的成员
s.copy() 返回一个新集合,它是集合 s 的浅复制
很多内建的方法几乎和操作符等价。我们说"几乎等价",意思是它们间是有一个重要区别: 当用操作符时,操作符两边的操作数必须是集合。 在使用内建方法时,对象也可以是迭代类型的。为什么要用这种方式来实现呢? Python 的文档里写明: 采用易懂的 set('abc').intersection('cbs') 可以避免用 set('abc') 'cbs' 这样容易出错的构建方法。
表 7.5 可变集合类型的方法
方法名 操作
s.update(t) 用 t 中的元素修改 s, 即,s 现在包含s或t 的成员
s.intersection_update(t) s 中的成员是共同属于s和t 的元素。
s.difference_update(t) s 中的成员是属于 s 但不包含在 t 中的元素
s.symmetric_difference_update(t) s 中的成员更新为那些包含在s或t 中,但不 是s 和 t 共有的元素
s.add(obj) 在集合 s 中添加对象 obj
s.remove(obj) 从集合s中删除对象obj; 如果obj不是集合s中的元素(obj not in s),将引发 KeyError 错误
s.discard(obj) 如果 obj 是集合 s 中的元素,从集合 s 中删除对象 obj;
s.pop() 删除集合 s 中的任意一个对象,并返回它
s.clear() 删除集合 s 中的所有元素
页:
[1]