八:python 对象类型详解四:字典

时间:2021-03-13 15:08:37

一:字典通识:

  1,字典通过键而不是偏移量来读取;

  2,字典是任意对象的无序集合;

  3,字典可变长、异构、任意嵌套;

  4,字典属于可变映射类型;

  5,对象引用表(散列表);

二:实际应用中的字典:

  1,字典的基本操作:创建和读取字典,使用相同的方括号语法,用键对字典进行索引操作。创建字典的方式:

>>>D = {'a' : 0,'b' : 0}  #常量表达式创建
>>>D
{'a' : 0,'b' : 0}
>>>D = {} #通过赋值运算创建
>>>D['a'] = 0
>>>D['b'] = 0
>>>D
{'a' : 0,'b' : 0}
>>>D = dict(a = 0,b = 0) #通过关键字形式创建
>>>D
{'a' : 0,'b' : 0}
>>>D = dict([('a',0),('b',0)]) #通过键/值对序列的形式创建
>>>D
{'a' : 0,'b' : 0}
>>>D = dict.fromkeys(['a','b'],0) #特殊情况可用内置函数创建
>>>D
{'a' : 0,'b' : 0}
>>>D = {k : 0 for k in 'ab'} #python3.0中可以使用字典解析来创建
>>>D
{'a' : 0,'b' : 0}

字典创建的方法

  2,原处修改字典:python 中,所有集合数据类型都可以彼此任意嵌套。与列表相同,向字典中已经存在的索引赋值会改变与索引相关联的值。然而,与列表不同的是,每当对新字典键进行赋值的时候,就会在字典中生成一个新的元素。

>>>D = {'a':1,'b':2}   #不同数据类型相互嵌套
>>>D['c'] = [3,4,5] #新创建一个元素
>>>D
{'a':1,'b':2,'c':[3,4,5]}
 

  3,其它字典方法:字典方法提供了多种工具,例如,字典values 和 items 方法分别返回字典的值列表和(key,value)对元组,在python3.0 中将它们放入到一个list 列表中,用来收集它们的值以显示:

>>>D = {'spam':2,'ham':1,'eggs':3}
>>>list(D.values())
[3,1,2]
>>>list(D.items())
[('eggs',3),('ham',1),('spam',2)] #返回键值对的列表

  字典的update() 方法有点类似于合并,但是,它和从左到右的顺序无关,它把一个字典的键和值合并到另一个字典中,盲目地覆盖相同键的值。字典的pop() 方法能够从字典中删除一个键并返回它的值。这类似于列表的pop() 方法,只不过删除的是一个键而不是一个可选的位置:

>>>D = {'spam':2,'ham':1,'eggs':3}
>>>D2 = {'toast':4,'muffin':5}
>>>D.update(D2) #类似于合并的功能
>>>D
{'spam':2,'ham':1,'eggs':3,'toast':4,'muffin':5}
>>>D.pop('muffin') #删除了键值为 muffin 的项
5 #返回删除项的 value
>>>D
{'spam':2,'ham':1,'eggs':3,'toast':4,}

三:语言表:

  

>>>table = {'python':'Guido','Perl':'Larry','Tcl':'John'}
>>>language = 'python'
>>>creator = table[language]
>>>creator
'Guido'
>>>for lang in table: #such as:for lang in table.keys()
... print(lang, '\t', table[lang])
Tel Jonh
python Guido
Perl Larry

因为字典并非序列,你无法像字符串和列表那样直接通过一个for 循环语句迭代它们。但是,如果你需要遍历各项是很容易的:调用字典的keys()方法,返回经过排序之后所有键的列表,再用for循环进行迭代。实际上,python 能让你遍历字典的键列表,而并不用在多数for循环中调用keys() 方法。就任何字典而言: for key in D: 和 key in D.keys():  效果是一样的。

四:字典用法注意实事项:

  1,序列运算无效;

  2,对新索引赋值会添加项;

  3,键不一定总是字符;

  4,使用字典模拟灵活的列表:当使用列表的时候,对在列表末尾外的偏移赋值是非法的,虽然可以可以使用重复按所需预先分配([0] * 100),但你也可以用字典来做类似的事情,这样就不需要这样的空间分配了。使用整数键时,字典可以效仿列表在偏移赋值时增长:

>>> L = []
>>> L[99] = 'spam'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
>>>D = {} #用字典模拟列表实现
>>>D[99] = 'spam'
>>>D[99]
'spam
>>>D
{99:'spam'}'

  5,字典用于稀疏数据结构:

>>>Matrix = {}
>>>Matrix[(2,3,4)] = 88
>>>Matrix[(7,8,9)] = 99
>>>
>>>x = 2; y = 3; z = 4
>>>Matrix[(x,y,z)]
88
>>>Matrix
{(2,3,4):88,(7,8,9):99}

在这里,我们用字典表示一个三维数组,这个中只有两个位置(2,3,4)和(7,8,9)有值,其余位置都为空。键是元组,它们记录非空元素的坐标。我们并不需要分配一个庞大而几乎为空的三维矩阵,而是用一个简单的两个元素的字典。

  6,避免missing-key 错误:读取不存在的键的错误在稀疏矩阵中很常见,然而我们可能并不希望程序因为这一错误被关闭。下面的方式可以比秒这个错误:

>>>if (2,3,6) in Matrix:            #方法一
... printf(Matrix[(2,3,6)])
else:
... print(0)
...
0
>>>try : #方法二
... printf(Matrix[(2,3,6)])
... except KeyError:
... print(0)
...
0
>>>Matrix.get((2,3,4),0) #方法三
88
>>>Matrix.get((2,3,6),0)
0

avoid missing-key error

  7,使用字典作为记录:

>>> mel = {'name':'Mark','Jobs':['trainer','writer'],'web':'www.rmi.net/','home':{'state':'CO','zip':80513}}
>>> mel['name']
'Mark'
>>> mel['Jobs']
['trainer', 'writer']
>>> mel['Jobs'][1] #读取嵌套对象的元素时,只要简单地把索引操作串起来就可以
'writer'

五:Python 3.0 中的字典变化

  1,对于D.key、D.value 和D.item 方法,返回可迭代的视图,而不是列表。可以使用list() 收集。

  2,不在直接支持相对大小比较--取而代之的是手动比较。

  3,不再有D.has_key 方法,相反,使用 in 成员关系测试。

  4,字典解析:字典解析隐式地运行一个循环,根据每次迭代收集表达式的键/值结果,并且用它们来填充一个新的字典。动态初始化一个字典的标准方式都是:将其键和值对应起来并把结果传递给dict 调用。另外,zip 函数是在一个单个调用中从键和值的列表来构建一个字典的方式之一。

>>>list(zip(['a','b','c'],[1,2,3]))   #Zip togerther keys and values
[('a',1),('b',2),('c',3)]
>>>D = dict(zip(['a','b','c'],[1,2,3]))
>>>D
{'a':1,'b':2,'c':3}
>>>
>>>D = {k: v for (k,v) in zip(['a','b','c'],[1,2,3])} #字典解析表达式来实现
>>>D
{'a':1,'b':2,'c':3}

  5,formkeys 方法:

>>>D = dict.fromkeys(['a','b','c'],0)
>>>D
{'a':0,'c':0,'b':0}
>>>D = dict.fromkeys('spam') #默认值为None
>>>D
{'a':None,'p':None,'s':None,'m':None}

  6,字典视图:在python3.0 中,字典的keys 、values 和items 都返回视图对象,而在python 2.6中,它们返回实际的结果列表。视图是可迭代的,这就意味着对象每次产生一个结果项,而不是在内存中立即产生结果列表。除了是可迭代的,字典视图还保持了字典成分的最初的顺序,反映字典未来的修改,并且能够支持集合操作。如果我们想要应用列表操作或者显示它们的值,我们必须通过内置函数list来运行这个结果。

 
>>> D = dict(a = 1,b = 2,c = 3)
>>> D
{'a': 1, 'b': 2, 'c': 3}
>>> K = D.keys()
>>> K
dict_keys(['a', 'b', 'c']) #视图对象显示为dict_keys 的形式
>>> list(K)
['a', 'b', 'c']
>>> V = D.values()
>>> V
dict_values([1, 2, 3]) #视图对象显示为dict_values 的形式
>>> list(V)
[1, 2, 3]
>>> K[0]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'dict_keys' object does not support indexing #视图不支持索引
>>> list(K)[0]
'a'

python 3.0 中的字典视图并非创建后不能改变,它们可以动态地反映在视图对象创建之后对字典做出的修改:

>>> D = {'a':1,'b':2,'c':3}
>>> D
{'a': 1, 'b': 2, 'c': 3}
>>> K = D.keys() #View maintain same order as dictionary
>>> V = D.values()
>>> list(K)
['a', 'b', 'c']
>>> list(V)
[1, 2, 3]
>>> del D['b'] #Change the dictionary in-place
>>> D
{'a': 1, 'c': 3}
>>> list(K) #Reflected in any current view objects
['a', 'c']
>>> list(V)
[1, 3]

  7,字典视图和几何:keys()方法所返回的Python 3.0 的视图对象类似于集合,并且支持交集和并集等常见的几何操作;但是,value 视图不是这样的,因为它们不是唯一的,但items 结果是的,如果(key,value)对是唯一的并且可以散列的话。如下是键列表用于集合操作中的样子。在集合操作中,视图可能与其他的视图、集合和字典混合(在这种环境下,字典与它们的键视图一样对待):

>>> K
dict_keys(['a', 'c'])
>>> K | {'x':4}
{'x', 'a', 'c'}
>>> V & {'x':4} #values 视图不是这样的,不能进行集合操作
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for &: 'dict_values' and 'dict'
>>>
>>> D = {'a':1,'b':2,'c':3}
>>> D.keys() & {'b'}
{'b'}
>>> D.keys() & {'b':1} #字典与它们的键视图一样对待
{'b'}

  8,排序字典键:首先,由于keys 不会返回一个列表,在python 2.x 中通过排序键来浏览一个字典的编码模式,在python 3.0 中并不适用。要么手动地转换为一个列表,要么在一个键视图或字典自身上使用sorted()函数调用:

>>> D
{'a': 1, 'b': 2, 'c': 3}
>>> Ks = D.keys()
>>> Ks.sort() #视图不能进行排序
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'dict_keys' object has no attribute 'sort'
>>> Ks = list(Ks) #手动转换为列表,然后进行排序
>>> Ks.sort()
>>> for k in Ks: print(k,D[k])
...
a 1
b 2
c 3
>>> D
{'a': 1, 'b': 2, 'c': 3}
>>> Ks = D.keys()
>>> for k in sorted(Ks):print(k,D[k]) #使用sorted()函数进行排序,返回列表
...
a 1
b 2
c 3
>>>
>>> D
{'a': 1, 'b': 2, 'c': 3}
>>> for k in sorted(D):print(k,D[k]) #直接使用sorted()和dict
...
a 1
b 2
c 3

  9,has_key 方法已死,in永生:广为使用的has_key 键存在测试方法在python3.0 中取消了。相反,使用 in 关系表达式,或者带有默认测试的一个get(in 通常是首选):

>>> D
{'a': 1, 'b': 2, 'c': 3}
>>> D.has_key('c') #已经被取消
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'has_key'
>>> 'c' in D
True
>>> print(D.get('c'))
3 #返回键对应的值
>>> print(D.get('x')) #default return None
None