字典(dict)
dict(字典)可能是python内建数据结构中最重要的。它有更为常用的名字就是哈希表或者是关联数值。
字典是拥有灵活尺寸的键值对集合,其中键和值都是python对象。创建字典的方式是用大括号{ }创建,在字典中用逗号将键值对分隔:
d1 = {'a':'some value','b':[1,2,3,4]}
d1
{'a': 'some value', 'b': [1, 2, 3, 4]}
字典的访问
字典的访问、插入或设置字典中的元素,就像访问列表和元组中的元素一样,同样你可以用检查列表或元组中是否含有一个相同元素的语法来检查字典是否含有一个键:
d1[7] = 'an integer'
d1
{'a': 'some value', 'b': [1, 2, 3, 4], 7: 'an integer'}
d1['b']
[1, 2, 3, 4]
'b' in d1
True
字典的删改
同样你也可以使用del关键字和pop方法删除值,pop方法会在删除的同时返回被删除的值并且删除键:
d1[5] = 'some value'
d1[6] = ['anther value']
d1
{'a': 'some value',
'b': [1, 2, 3, 4],
7: 'an integer',
5: 'some value',
6: ['anther value']}
del d1 [5]
d1
{'a': 'some value', 'b': [1, 2, 3, 4], 7: 'an integer', 6: ['anther value']}
p = d1.pop(6)
p
['anther value']
d1
{'a': 'some value', 'b': [1, 2, 3, 4], 7: 'an integer'}
字典的合并
在python中你可以使用update方法将两个字典合并,update方法会改变字典中的元素位置,因此对于任何原字典已经存在的键,如果传给update方法的数据也含有相同的键,则它的值将会被覆盖:
d1.update({'b':'foo','c':12})
d1
{'a': 'some value', 'b': 'foo', 7: 'an integer', 'c': 12}
keys方法和values方法会分别为你提供字典键、值的迭代器。然而键值对并没有特定的顺序,函数输出的键、值都是按照相同的顺序:
list(d1.keys())
['a', 'b', 7, 'c']
list(d1.values())
['some value', 'foo', 'an integer', 12]
从序列生成字典
通常情况下,你会有两个序列想要在字典中按元素配对。刚开始,你可能会写出:
mapping = {}
a = [1,2,3,4,5]
b = [6,7,8,9]
for key,value in zip(a,b):
mapping[key] = value
mapping
{1: 6, 2: 7, 3: 8, 4: 9}
由于字典本质上是2-元组(含有2个元素的元组)的集合。字典是可以接受一个2-元组的列表作为参数的:
mapping = dict(zip(range(5),reversed(range(5))))
mapping
{0: 4, 1: 3, 2: 2, 3: 1, 4: 0}
字典的默认值
通常情况下,会有这样的代码逻辑:
if key in dict:
value = dict[key]
else:
value = default_value
不过字典的get方法和pop方法可以返回一个默认值。因此上面的方法还可以被简写为:
value = dict.get(key,default_value)
带有默认值的get方法会在key参数不是字典的键时返回None,而pop方法则会抛出异常。一个常见的场景是字典中的值集合通过设置,成为另一种合集,比如列表,你可以想象一下将字词组成的列表根据首字母分类为包含列表的字典:
words = ['apple','bat','bar','atom','book']
by_letter = {}
for word in words:
letter = word[0]
if letter not in by_letter:
by_letter[letter] = [word]
else:
by_letter[letter].append(word)
by_letter
{'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']}
而字典的setdefault方法就是为了这个目的而产生的,setdefault方法的意思为:“如果键不存在于字典中,将会添加键并将值设为默认值。”使用setdefault方法上述的for循环语句可以简写为:
for word in words:
letter = word[0]
by_letter.setdefault(letter,[]).append(word)
by_letter
{'a': ['apple', 'atom', 'apple', 'atom'],
'b': ['bat', 'bar', 'book', 'bat', 'bar', 'book']}
内建的集合模块中有一个非常有用的类,defaultdict。这个类会使上述目的的实现更为简单,想要生成符合要求的字典,你可以向字典传入类型或能在各位置生成默认值的函数:
from collections import defaultdict
by_letter = defaultdict(list)
for word in words:
by_letter[word[0]].append(word)
by_letter
defaultdict(list, {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']})
有效的字典键类型
尽管字典的值可以是任何python对象,但键必须是不可变对象,比如标量类型或元组。这里要使用到一个术语叫做哈希化,通过hash函数可以检查一个对象是否可以哈希化(即是否可以用作字典的键):
hash('python')
-7320113093703743264
hash((1,2,(2,3)))
1097636502276347782
hash((1,2,[2,3]))
TypeError Traceback (most recent call last)
<ipython-input-29-576218ff90d3> in <module>()
----> 1 hash((1,2,[2,3]))
TypeError: unhashable type: 'list'
为了将列表作为键,一种方式就是将其转换为元组,而元组只要它内部元素都可以哈希化,则它自己也可以哈希化:
d = {}
d[tuple([1,2,3])] = 5
d
{(1, 2, 3): 5}
上述就是python中字典的用法.