08-02字典
字典
字典是一种key-value结构
字典对象操作
新建字典
- 方式1:d = {}
- 方式2:d = dict()
- 方式3:d =
- 方式4:d = dict([('a',1), ('b', 2)]) # 可迭代对象的元素必须是一个二元组, 二元组的第0个元素为字典的key, 第一个元素为字典的value。
- 方式5:传入的可迭代元素为key, 值为None。
In [26]: dict.fromkeys(range(5)) # 传入的可迭代元素为key, 值为None。
Out[26]: {0: None, 1: None, 2: None, 3: None, 4: None}
In [27]: d = dict.fromkeys(range(5), 'abc') # 传入的可迭代对象的元素为key, 值为abc。
In [28]: d
Out[28]: {0: 'abc', 1: 'abc', 2: 'abc', 3: 'abc', 4: 'abc'}
- 方法6:接收一个字典,不常用
- 例如:In [33]: d = dict({'a':1, 'b':3}) # 接收一个字典
删除字典
字典元素的操作
增加与修改
- 可以直接下标操作,如果key不存在则会增加kv对,如果key存在则会修改其value
- d.update([('c', 3), ('p', 0)]):传入一个字典,该方法通常用于合并字典
In [30]: d['acc'] = 5 # 可以直接使用key做为下标, 对某个不存在的下标赋值, 会增加kv对。
In [31]: d.update([('c', 3), ('p', 0)]) # update传入参数和dict一样
In [32]: d
Out[32]: {0: 'abc', 1: 'abc', 2: 'abc', 3: 'abc', 4: 'abc', 'acc': 5, 'c': 3, 'p': 0}
In [34]: d.update({'r': 2, 'd': 3}) # update通常用于合并字典
In [36]: d.update([('r', 2), ('d', 2)]) # 传入一个值
In [37]: d['a'] = 2 # 当key存在, 对下标赋值的时候, 会修改这个key对应的value。
删除
- d.pop(0):pop方法用于从字典删除一个key, 并返回其value。当key不存在时会抛出KeyError
- d.pop(0, 'defalut'): 当删除不存在的key, 并且指定了默认值时, 不会抛出KeyError, 并且返回默认值
- d.popitem():popitem随机返回并删除一个kv对的二元组,如果空字典则会抛出KeyError
- d.clear():clear方法清空一个字典
- del d['c']:不过通常用pop删除key
In [4]: d.pop(0) # pop方法用于从字典删除一个key, 并返回其value
Out[4]: 'abc'
In [5]: d.pop(0) # 当删除不存在的key的时候, 会抛出KeyError
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-5-e1702b259b84> in <module>()
----> 1 d.pop(0)
KeyError: 0
In [6]: d.pop(0, 'defalut') # 当删除不存在的key, 并且指定了默认值时, 不会抛出KeyError, 并且返回默认值
Out[6]: 'defalut'
In [7]: d.pop(1, 'default') # 有没有default, 是在key不存在的时候才有所区别。
Out[7]: 'abc'
In [8]: d.popitem() # popitem随机返回并删除一个kv对的二元组
Out[8]: (2, 'abc')
In [9]: d.clear() # clear方法清空一个字典
In [10]: d.popitem() # 对空字典popitem, 将抛出KeyError
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-10-5d3e77a54ba7> in <module>()
----> 1 d.popitem()
KeyError: 'popitem(): dictionary is empty'
In [12]: del d['c'] # 不过通常用pop删除key
访问
单个元素的访问
- d['d']:通过key访问value,当key不存在的时候抛出KeyError
- d.get('d'):get方法通过key访问value,get方法访问不存在的key的时候返回None
- d.get('c', 'default'):事实上get方法访问不存在的key的时候, 返回默认值, 默认值默认为None
- d.setdefault('c', 'default'):当一个key存在value的时候, 返回value, 如果不存在, 就添加其kv对。
In [2]: d = {'d': 2, 'p':0, 'r': 2}
In [3]: d['d'] # 通过key访问value
Out[3]: 2
In [4]: d['c'] # 当key不存在的时候抛出KeyError
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-4-3e4d85f12902> in <module>()
----> 1 d['c']
KeyError: 'c'
In [5]: d.get('d') # get方法通过key访问value
Out[5]: 2
In [6]: d.get('c') # get方法访问不存在的key的时候返回None
In [9]: d.get('c', 'default') # 事实上get方法访问不存在的key的时候, 返回默认值, 默认值默认为None
Out[9]: 'default'
d.setdefault:当一个key存在value的时候, 返回value, 如果不存在, 就添加其kv对。
In [10]: d.setdefault('c', 'default') # c不存在
Out[10]: 'default'
In [11]: d
Out[11]: {'c': 'default', 'd': 2, 'p': 0, 'r': 2}
In [12]: d.setdefault('d', 'default')
Out[12]: 2
setdefault的实现:
In [13]: def setdefault(d, k, default=None):
...: value = d.get(k, default)
...: d[k] = value
...: return value
...:
字典的遍历
字典的元素是成对出现的
- 如果直接用for in遍历字典, 遍历的是字典的key
- d.values():value返回一个可迭代对象, 元素是字典的所有value
- items方法返回一个可迭代对象, 元素是字典的所有(k, v)对
- d.keys():eys方法返回一个可迭代对象, 元素是字典所有的key
In [14]: for x in d:
...: print(x)
...:
d
p
c
r
In [15]: d
Out[15]: {'c': 'default', 'd': 2, 'p': 0, 'r': 2}
直接用for in遍历字典, 遍历的是字典的key
In [17]: d.values() # value返回一个可迭代对象, 元素是字典的所有value
Out[17]: dict_values([2, 0, 'default', 2])
In [19]: for v in d.values(): # 返回values
...: print(v)
...:
2
0
default
2
In [20]: d.items() # items方法返回一个可迭代对象, 元素是字典的所有(k, v)对
Out[20]: dict_items([('d', 2), ('p', 0), ('c', 'default'), ('r', 2)])
In [21]: for x in d.items(): # key和value都出现
...: print(x)
...:
('d', 2)
('p', 0)
('c', 'default')
('r', 2)
In [22]: for k, v in d.items(): # key和value分开出现
...: print(k, v)
...:
d 2
p 0
c default
r 2
In [23]: d.keys() # keys方法返回一个可迭代对象, 元素是字典所有的key
Out[23]: dict_keys(['d', 'p', 'c', 'r'])
python2与Python3的不同
python2中返回的都是一个列表, python3中返回的是可迭代对象
区别:python3中的keys, values, items返回的都是生成器, 它并不会复制一份内存。
python2中对应的函数返回的是列表, 会复制一份内存。
Python 2.7.5 (default, Nov 6 2016, 00:28:07)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> d = {'r': 2, 'd': 2, 'c': 3, 'p
File "<stdin>", line 1
d = {'r': 2, 'd': 2, 'c': 3, 'p
^
SyntaxError: EOL while scanning string literal
>>> d = {'r': 2, 'd': 2, 'c': 3, 'p': 0}
>>> type(d.keys())
<type 'list'>
>>> type(d.items())
<type 'list'>
>>> type(d.values())
<type 'list'>
字典的限制
- 字典是无序的
- 字典的key不能重复
- 字典的key需要可hash
In [24]: d = {}
In [25]: d[[1, 2, 3]] = 3 # 不可hash的key会报错
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-25-1b5d054185d2> in <module>()
----> 1 d[[1, 2, 3]] = 3
TypeError: unhashable type: 'list'
In [26]: d[(1, 2, 3)] = 3
In [27]: d
Out[27]: {(1, 2, 3): 3}
In [28]: d[0] = [1, 2, 3] # 字典的value是没有限制的
In [29]: d
Out[29]: {0: [1, 2, 3], (1, 2, 3): 3}
In [30]: hash(d) # 字典不是可hash的, 所以不能做set的元素
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-30-a37dc9dc2032> in <module>()
----> 1 hash(d)
TypeError: unhashable type: 'dict'
标准库中两个字典的变体
默认字典
- 默认字典的定义:d2 = defaultdict()
- 默认字典的初始值:defaultdict(None, {})
In [31]: from collections import defaultdict
In [32]: d1 = {} # 普通字典
In [33]: d2 = defaultdict() # 默认字典
In [34]: d1 # 普通字典的初始值
Out[34]: {}
In [35]: d2
Out[35]: defaultdict(None, {}) # 默认字典的初始值
In [40]: d2 = defaultdict(list)
In [41]: d1['a']
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-41-a9ea8faf9ae0> in <module>()
----> 1 d1['a']
KeyError: 'a'
In [42]: d2['a'] # 得到一个list
Out[42]: []
default初始化的时候, 需要传入一个函数, 这个函数也叫工厂函数, 当我们使用下标访问一个key的时候, 如果这个key不存在, defaultdict会自动调用初始化时传入的函数, 生成一个对象做为这个key的value
In [43]: d = {}
...: for k in range(10):
...: for v in range(10):
...: if k not in d.keys():
...: d[k] = []
...: d[k].append(v)
...:
In [44]: d = defaultdict(list)
In [45]: for k in range(10):
...: for v in range(10):
...: d[k].append(v)
...:
有序字典
In [46]: from collections import OrderedDict
In [47]: d = OrderedDict()
In [48]: d[0] = 3
In [49]: d[3] = 4
In [50]: d
Out[50]: OrderedDict([(0, 3), (3, 4)])
In [51]: for k, v in d.items():
...: print(k, v)
...:
0 3
3 4
有序字典, 会保持插入顺序
In [53]: def f():
...: print('f is called')
...: return 'a'
...:
In [54]: d = defaultdict(f)
In [55]: d['xxx']
f is called
Out[55]: 'a'
In [56]: d['yyy']
f is called
Out[56]: 'a'
In [57]: d['xxx']
Out[57]: 'a'
字典总结
字典:
增加/修改:
下标操作
update
删除
pop()
有默认值
无默认值的区别
popitem
无序的
clear
del 语句
访问:
单个元素:
下标
get
setdefault
遍历:
keys
values
items
限制:
key必须是可hash