目录python
在Python中字典属于一种映射类型,它和set相同,一样属于非线性结构存储,Python官方对dict有以下解释linux
简单来讲:字典是由key:value键值对组成的数据的集合,它的主要特色是 可变的
、无序的
、不重复的
。centos
字典的key必须是可hash对象。数据结构
字典是除set集合之外另外一种可变的非线性容器模型,在Python中很是强大,适合各类结构数据的存储、嵌套等。app
字典的每一个key到value的键值对用冒号(:)分割,每对之间用逗号(,)分割,整个字典包括在花括号({})中。例:{'a':1, 'b':2}
,Python提供了多种建立字典的方式,以下:函数
d = dict()
或者 d = {}
dict(**kwargs)
: 使用name=value对,来初始化一个字典dict(iterable, **kwargs)
:使用可迭代对象和name=value构造字典,注意可迭代对象必须是一个二元结构
dict(mapping, **kwargs)
: 使用一个字典构造另外一个字典dic = {'a':1, 'b':2, 'c':3, 'd':[1,2,3]}
dic = dict.fromkeys(iterable, value)
: 使用可迭代对象的值做为key生成字典,value默认为0,不然用指定的value对字典进行初始化。In [114]: d1=dict() In [115]: d2={} In [118]: d3 = dict(a=1,b=2) In [120]: d3 Out[120]: {'a': 1, 'b': 2} In [124]: d4 = dict([('a',1),('b',2)], c=3, d=4) In [125]: d5 = dict(d4,e=5,f=6) In [126]: d7 = dict.fromkeys(range(5)) In [127]: d8 = dict.fromkeys(range(5),100) In [128]: d7 Out[128]: {0: None, 1: None, 2: None, 3: None, 4: None} In [131]: d8 Out[131]: {0: 100, 1: 100, 2: 100, 3: 100, 4: 100}
有以下三种方式访问字典的键值对:优化
d[key]
: 返回key对应的value,key不存在抛出KeyError异常dict.get(key[, default])
: 返回key对应的value,key不存在返回缺省值,若是没有设置缺省值赶回Nonedict.setdefault(key[, default])
: 返回key对应的值value,key不存在,添加key:value键值对(value设置为default),并返回value,若是default没有设置缺省为NoneIn [32]: dic = {'a':1, 'b':2, 'c':3, 'd':4} In [33]: dic['a'] Out[33]: 1 In [34]: dic['e'] # 不存在'e'这个key,因此直接访问会出现异常 --------------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-34-87d22c709971> in <module> ----> 1 dic['e'] KeyError: 'e' In [35]: dic.get('a') # key存在,则返回对应的值 Out[35]: 1 In [36]: dic.get('e') # 不存在,默认会返回None,ipython优化了None的输出,因此这里无显示 In [37]: dic.get('e','not exist') # 不存在时,由指定的default进行返回 Out[37]: 'not exist' In [38]: dic.setdefault('a', 'ok?') # 设置a的值为ok?,a存在,因此返回a对应的值1 Out[38]: 1 In [39]: dic.setdefault('e', 'ok?') # 设置e的值为ok?,e不存在,因此设置并放回value(key不存在时等同于设置并访问了) Out[39]: 'ok?' In [40]: dic Out[40]: {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 'ok?'}
固然字典也能够被迭代访问,后面介绍centos7
因为字典可变、非线性、无序的特性,并且字典的key必须是可hash的对象,查找某个key也是直接hash(),而后找到对应的房间的,因此咱们对它某个key的修改能够理解为是O(1)
的操做,效率很高,主要有如下几种方法。code
d[key] = value
: 将key对应的值修改成value,key不存在添加新的key:value对。dic.update([other]) --> None
: 使用另外一个字典的k,v对更新本字典,key不存在时添加,存在时则覆盖,因此不会返回新的字典,属于原地修改。dic.pop(key[, default])
: key存在,移除它,并返回它的value,key不存在返回指定的default,若是default未指定,那么会返回KeyError异常。dic.popitem()
: 移除并返回一个任意的键值对,字典为empty时,抛出KeyError异常。dic.clear()
: 清空字典。del dic['a']
: 通用的删除变量方法。In [41]: dic Out[41]: {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 'ok?'} In [42]: dic['a'] = 1000 In [43]: dic Out[43]: {'a': 1000, 'b': 2, 'c': 3, 'd': 4, 'e': 'ok?'} In [44]: dic2 = {'a':200,'f':50} In [45]: dic.update(dic2) In [46]: dic Out[46]: {'a': 200, 'b': 2, 'c': 3, 'd': 4, 'e': 'ok?', 'f': 50} In [48]: dic.pop('a') # 弹出一个key'a',key存在返回key对应的value Out[48]: 200 In [49]: dic.pop('g') # 弹出一个key'g',key不存在,又没有指定default,则会报KeyError异常 --------------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-49-311c3ba80251> in <module> ----> 1 dic.pop('g') KeyError: 'g' In [50]: dic.pop('g','not exist') # 指定了default,当key不存在时,会返回指定的default值 Out[50]: 'not exist' In [51]: dic.popitem() # 弹出一个key:valyue键值对,返回对象是元组形式 Out[51]: ('d', 4) In [52]: dic Out[52]: {'b': 2, 'c': 3, 'e': 'ok?', 'f': 50} In [53]: del dic['e'] In [54]: dic Out[54]: {'b': 2, 'c': 3, 'f': 50} In [55]: dic.clear() In [56]: dic Out[56]: {}
当咱们以字典的某个对象好比keys,values,items等为条件对字典进行遍历时,咱们不能在遍历的同时删除字典的元素,字典在运行时不容许长度改变,可是在list中这种操做是能够的,可是会获得意想不到的结果,建议对容器进行遍历的同时不要修改它的长度。orm
In [7]: s Out[7]: {'a': 1, 'b': 2, 'c': 4, 'd': 5, 'e': 7, 'j': 10} In [8]: len(s) Out[8]: 6 In [10]: for i in range(6): ...: s.popitem() ...: In [11]: s Out[11]: {} # 下面这种方式是错的,也是以为不能够的。 for i in s.keys(): s.pop(i)
在Python中,咱们所说的基本数据结构:字符串、元组、列表,集合,包括字典,均可以认为是一个容器箱子,只要是容器,咱们就能够进行遍历(是否有序和是否能够遍历没有必然关系,只不过有序的话是顺序拿出,而无序则是随机拿出),咱们可使用多种方式对字典进行迭代遍历,可是有些地方和其余类型不一样。
dic.keys()
: --> dict_keys
--> 返回字典dic的全部key组成的一个dict_keys视图集合(类set结构,不会生成新的内存空间
)。
In [64]: dic = {'a':1, 'b':2, 'c':3, 'd':4} In [65]: for key in dic: ...: print(key) a d c b In [66]: for key in dic.keys(): ...: print(key) a d c b In [67]: dic.keys() Out[67]: dict_keys(['a', 'd', 'c', 'b'])
迭代字典就是在迭代字典的key,因此直接迭代字典和使用字典的keys()方法返回一个keys的视图而后再迭代,是同样的效果。
dic.values()
: --> dict_values
--> 返回字典dic的全部values组成的一个dict_values视图集合(类set结构,不会生成新的内存空间
)。
In [69]: for i in dic: ...: print(dic[i]) 1 4 3 2 In [70]: for i in dic.values(): ...: print(i) 1 4 3 2 In [71]: dic.values() Out[71]: dict_values([1, 4, 3, 2])
能够首先遍历字典的key,而后再经过key来访问对应的value,也能够经过values()直接访问values。
dic.items()
: --> dict_items
--> 返回字典dic的全部的key和value(每一个key和value的键值对由元组表示)组成的一个dict_items视图集合(类set结构,不会生成新的内存空间
)。
In [75]: for i in dic.items(): ...: print(i) ...: ('a', 1) ('d', 4) ('c', 3) ('b', 2) In [77]: for key,value in dic.items(): ...: print('key:{} value:{}'.format(key,value)) ...: key:a value:1 key:d value:4 key:c value:3 key:b value:2 In [78]:
因为返回的每一个键值对为元组格式,那么利用咱们前面学的封装与结构,能够很方便的获取key和它对应的value
在Python3中,keys、values、items方法返回一个相似一个生成器的可迭代对象,不会把函数的返回结果复制到内存空间中。
[11:20:32 python@centos7 ~]$python Python 2.7.5 (default, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> s = {'a':1,'b':2} >>> s.keys() # 直接生成一个keys的列表 ['a', 'b'] >>> s.iterkeys() # 对象,迭代能够获取数据 <dictionary-keyiterator object at 0x7f271c5fa520> >>>
defaultdit object是dict的子类,咱们称它为默认值字典,即在建立字典时给全部的value指定一个默认值,它存放在collections模块中,使用前须要先进行导入。为何有默认值字典这种类型呢?那么请看以下代码:
dic = {} for i in 'abacdabeddfef': if i not in dic: # 这句其实也能够优化为 dic[i] = dic.get(i, 0) + 1 dic[i] = 0 dic[i] += 1 print(dic)
咱们在计算一个字符串或者一个列表中的元素重复的次数时,一般会用到字典对齐进行计数,若是元素不存在字典中,那么就须要初始化元素,当咱们使用默认值字典时,就能够优化的更简洁。
from collections import defaultdict dic = defaultdict(int) # defaultdict(lambda :0) 这种方法也能够设置默认为0 for i in 'abacdabeddfef': dic[i] += 1 # 默认是int型,能够直接加减 print(dic)
Ordered dictionaries像一个有序字典,可是它记住的是插入元素的顺序。当咱们迭代有序字典时,它会按照这些键值对插入的顺序返回。它一样存在于collections模块中,须要使用是请首先导入。
In [1]: from collections import OrderedDict In [2]: dic = OrderedDict() In [5]: dic = dic.fromkeys('abc',1) In [6]: dic Out[6]: OrderedDict([('a', 1), ('b', 1), ('c', 1)]) In [8]: for k,v in dic.items(): # 按照插入的顺序 ...: print(k,v) ...: a 1 b 1 c 1 In [10]: dic = dict([('a', 1), ('b', 1), ('c', 1)]) In [11]: for k,v in dic.items(): # 无序的 ...: print(k,v) ...: a 1 c 1 b 1 In [12]:
注意:在3.6的版本的python在python/ipython解释器中,直接迭代或者打印时,是有序的(OrderedDict),可是在3.5版本之前都是随机的,千万不要觉得字典是有序的!