python字典和集合
Posted Sakura
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python字典和集合相关的知识,希望对你有一定的参考价值。
构造方法与字典推导式
>>> a = dict(one=1, two=2, three=3) #法一 >>> b = {‘one‘: 1, ‘two‘: 2, ‘three‘: 3} #法二 >>> c = dict(zip([‘one‘, ‘two‘, ‘three‘], [1, 2, 3])) #法三 >>> d = dict([(‘two‘, 2), (‘one‘, 1), (‘three‘, 3)]) #法四 >>> e = dict({‘three‘: 3, ‘one‘: 1, ‘two‘: 2}) #法五 >>> a == b == c == d == e True
DIAL_CODES = [ #承载成对数据的列表,用于字典推导 (86, ‘China‘), (91, ‘india‘), (1, ‘United States‘), (7, ‘Russia‘), (81, ‘Japan‘), ] country_code = {country: code for code, country in DIAL_CODES} #字典推导式,类似于列表推导式 print(country_code) new_country_code = {code: country.upper() for country, code in country_code.items() if code > 80} #筛选code值大于60的并将country改为大写 print(new_country_code) #结果 {‘United States‘: 1, ‘Japan‘: 81, ‘Russia‘: 7, ‘india‘: 91, ‘China‘: 86} {81: ‘JAPAN‘, 91: ‘INDIA‘, 86: ‘CHINA‘}
dict常见方法(collections库中的defaultdict,Orderedict同样有这些方法)
1 dict.clear() //删除字典内所有元素
2 dict.copy() //返回一个字典的浅复制
3 dict.fromkeys(seq[, val]) //创建一个新字典,以序列 seq 中元素做字典的键,val 为字典所有键对应的初始值
4 dict.get(key, default=None) //返回指定键的值,如果值不在字典中返回default值
5 dict.has_key(key) //如果键在字典dict里返回true,否则返回false (可用key in dict代替)
6 dict.items() //以列表返回可遍历的(键, 值) 元组数组
7 dict.keys() //以列表返回一个字典所有的键
8 dict.setdefault(key, default=None) //和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default
9 dict.update(dict2) //把字典dict2的键/值对更新到dict里
10 dict.values() //以列表返回字典中的所有值以列表返回字典中的所有值
11 pop(key[,default]) //删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。
12 popitem() //随机返回并删除字典中的一对键和值。
找不到键时的选择
1.当字典d[k]不能找到正确的键的时候,会抛出keyError异常。上述方法中的dict.get(key, default=None)和dict.setdefault(key, default=None)均可解决问题。
而需要正确区分两个函数的合适场合,当需要更新某个键对应的值时,使用setdefault这个函数则更为合适,因为get函数只是返回default值,并不对字典进行更新。
2.使用collections中.defaultdict创建字典而不是dict
实例化defaultdict时,需要给构造方法提供一个可调用对象,这个可调用对象会在__getitem__碰到找不到的键的时候被调用,让__getitem__返回某个默认值。
以list为例,新建字典d = defaultdict(list),如果new_key在字典中不存在,则d[new_key]会按照以下步骤:
1)调用list来新建一个列表
2)把这个列表作为值,‘new_key’作为键,放到d中
3)返回列表引用。
其他映射类型
collections.OrderedDict //特点:添加键时保持顺序。popitem()方法删除的是最后一个元素,类似栈;而可用popitem(last=False)来删除第一个元素,类似队列。
collections.ChainMap //特点:可以容纳多个不同的映射对象,查找时,这些对象会被当做一个整体逐一查找,直到键被找到。
collections.Counter //特点:为键(key)维护一个计数器,每次更新一个键时会增加这个计数器。实现了+和-运算来合并记录。most_commot([n])方法,按照次序返回映射里面最常见的n个键和他们的计数。下例:
from collections import Counter ct = Counter(‘trueorfalse‘) print(ct) ct.update(‘tree‘) #更新 print(ct) print(ct.most_common(3)) #获取最多的三个键 new_ct = Counter(‘tree‘) print(ct + new_ct) #加号 print(ct - new_ct) #减号 Counter({‘r‘: 2, ‘e‘: 2, ‘u‘: 1, ‘o‘: 1, ‘a‘: 1, ‘t‘: 1, ‘s‘: 1, ‘l‘: 1, ‘f‘: 1}) Counter({‘e‘: 4, ‘r‘: 3, ‘t‘: 2, ‘u‘: 1, ‘o‘: 1, ‘a‘: 1, ‘s‘: 1, ‘l‘: 1, ‘f‘: 1}) [(‘e‘, 4), (‘r‘, 3), (‘t‘, 2)] Counter({‘e‘: 6, ‘r‘: 4, ‘t‘: 3, ‘u‘: 1, ‘o‘: 1, ‘a‘: 1, ‘f‘: 1, ‘l‘: 1, ‘s‘: 1}) Counter({‘r‘: 2, ‘e‘: 2, ‘u‘: 1, ‘o‘: 1, ‘a‘: 1, ‘t‘: 1, ‘f‘: 1, ‘l‘: 1, ‘s‘: 1})
自定义类型 UserDict
UserDict不是dict的子类,但UserDict有一个data属性,是dict的实例,data是UserDict最终存储数据的地方。
UserDict继承的是MutableMapping,MutableMapping继承的是Mapping。
MutableMapping.update不但可直接使用,而且用在__init__中,让构造方法可以利用各种参数(其他映射类型,可迭代的(key,value)元组对)来新建事例。
Mapping.get方法在键不存在时,将键转化为字符串查询。
不可变映射类型 types.MappingProxyType //返回一个动态视图
from types import MappingProxyType d = {1: ‘A‘} d_proxy = MappingProxyType(d) print(d_proxy) {1: ‘A‘} d_proxy[2] = ‘x‘ #不可变,抛出异常 Traceback (most recent call last): File "<input>", line 1, in <module> TypeError: ‘mappingproxy‘ object does not support item assignment d[2] = ‘x‘ print(d_proxy) #动态变化 mappingproxy({1: ‘A‘, 2: ‘x‘})
集合 (set和frozenset)
set本身元素必须是可散列的,但frozenset可以。
构造方法
s = {1,2,3} //速度快 s = set{[1,2,3]} //常用 s = frozenset([1, 2, 3, 4, 5, 4]) s = {i for i in range(5)} //集合推导式
一个陷阱:{ }构造的是一个字典而非集合,需用set()方法。
集合数学运算符(集合s和集合z,,以下方法会修改s)
交集 s & z s &= z
并集 s | z s |= z
差集 s z s = z
对称差集 s ^ z s ^= z
集合比较运算符(集合s和集合z,返回布尔值)
属于 e in s
子集 s <= z
真子集 s < z
父集 s >= z
真父集 s > z
其他常用方法
add(e) //向集合中添加元素e
clear() //清空集合
copy() //返回集合的浅拷贝
pop() //删除并返回任意的集合元素(如果集合为空,会引发 KeyError)
remove(e) //删除集合中的e元素(如果元素不存在,会引发 KeyError)
内置方法
all() //如果集合中的所有元素都是 True(或者集合为空),则返回 True。
any() //如果集合中的所有元素都是 True,则返回 True;如果集合为空,则返回 False。
enumerate() //返回一个枚举对象,其中包含了集合中所有元素的索引和值(配对)。
len() //返回集合的长度(元素个数)
max() //返回集合中的最大项
min() //返回集合中的最小项
sorted() //从集合中的元素返回新的排序列表(不排序集合本身)
sum() //返回集合的所有元素之和
字典实现方式(散列表)
4个问题
【1】字典和集合的效率?
【2】字典为什么是无序的?
【3】所有对象均可作为python中的键?
【4】为什么不能在迭代时往dict或set中添加元素。
散列表是一个稀疏数组(含有大量空白元素的数组),散列表单元称为表元。dict的散列表中,每个键值对占用一个表元,分为键的引用和值的引用两部分。表元大小一致,故通过偏移量来读取某个单元。python会设法保证大概有1/3的空白表元【1】,当达到这个阈值时,散列表会被复制到一个新的更大的空间中【2】【4】。(复制时会使用散列表算法)
散列性和相等性:字典必须保证键是可散列的【3】(在生命周期中,散列值是不变的对象);另外如果两个散列对象相等,那么他们的散列值相等,例如1和1.0。
散列表算法:获取d[k]的值时,会调用hash(k)来计算k的散列值,把这个值最低几位数字当做偏移量【5】,在散列表中查找表元,若表元为空,会抛出keyError异常;若不是空的,则产生散列冲突,算法会在散列值中另取几位,用特殊方法处理后,得到新的偏移量来查找表元。->反复如上步骤,直到产生keyError异常或查找到匹配的键。
上述特性分别决定了:
【1】字典在内存中开销巨大
【2】字典是可能是乱序的;【4】无论何时添加新的键都有可能让字典产生扩容,而这个过程会发生新的散列冲突,导致新散列表的键次序变化;而在迭代时修改字典可能会跳过一些键或迭代字典中已有的键。
【3】键必须是可散列的
【5】键查询很快
以上是关于python字典和集合的主要内容,如果未能解决你的问题,请参考以下文章