码迷,mamicode.com
首页 > 编程语言 > 详细

python字典和集合

时间:2019-01-06 21:10:08      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:子集   步骤   use   ini   typeerror   back   不可   而且   实例化   

构造方法与字典推导式

>>> 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字典和集合

标签:子集   步骤   use   ini   typeerror   back   不可   而且   实例化   

原文地址:https://www.cnblogs.com/lht-record/p/10230310.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!