Python 容器(二):字典(Dict)
一、字典
1、定义:Python的字典数据类型是基于hash散列算法实现的,采用键值对(key:value)的形式,根据key的值计算value的地址,具有非常快的查取和插入速度。
2、特点:
1)字典包含的元素个数不限; 2)值的类型可以是任何数据类型; 3)字典的key必须是不可变的对象,例如整数、字符串、bytes和元组,最常见的还是将字符串作为4)key。列表、字典、集合等就不可以作为key。 5)同时,同一个字典内的key必须是唯一的,但值则不必。 6)从Python3.6开始,字典是有序的。它将保持元素插入时的先后顺序。
2、创建字典
# dict()函数是Python内置的创建字典的方法。
dic = {} # 创建空字典
# 直接赋值,创建字典
dic = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}
# 通过dict()创建字典一
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'jack': 4098, 'guido': 4127}
# 通过dict()创建字典二
>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'jack': 4098, 'guido': 4127}
3、访问字典
虽然现在3.6版本后的字典在访问时有序了,但字典依然是集合类型,不是序列类型,因此没有索引下标的概念,更没有切片的说法。 但与list类似的地方是,字典采用把相应的键放入方括号内获取对应值的方式取值。
>>> fruit_dic = {'name':'apple', 'color':'red', 'shape':'round', 'taste':'sweet'}
>>> fruit_dic['name']
'apple'
# 如果访问一个不存在的key
>>> >>> fruit_dic['cc']
Traceback (most recent call last):File "<stdin>", line 1, in <module>
KeyError: 'cc'
4、增加和修改
增加就是往字典里插入新的键值对,修改就是给原有的键赋予新的值。由于一个key只能对应一个值,所有,多次对一个可以赋值,后面的值会把前面的值冲掉。
>>> fruit_dic = {'name':'apple', 'color':'red', 'shape':'round', 'taste':'sweet'}
>>> fruit_dic['name']
'apple'
>>> fruit_dic['name'] = 'lemon'
>>> fruit_dic['name']
'lemon'
>>> fruit_dic['name'] = 'banana'
>>> fruit_dic['name'] = 'cherry'
>>> fruit_dic
{'color': 'red', 'taste': 'sweet', 'shape': 'round', 'name':'cherry'}
# 上面字典的顺序出现的不同,是因为使用的是python2.7 。
# 通过for循环来创建(更新)字典
dic = {}
for i in "eafgdgd":dic[i] = ord(i)
print(dic)# {'e': 101, 'a': 97, 'f': 102, 'g': 103, 'd': 100}
5、 删除字典元素、清空字典和删除字典
>>> dic
{'Name': 'Jack', 'Age': '20', 'Class': 'First', 'sex': 'male'}
>>> del dic['Name'] # 删除指定的键
>>> dic
{'Age': '20', 'Class': 'First', 'sex': 'male'}
# ------------------
>>> a = dic.pop('Class') # 弹出并返回指定的键。必须提供参数!
>>> a
'First'
>>> dic
{'Name': 'Jack', 'Age': 7}
# ------------------
>>> dic.clear() # 清空字典
>>> dic
{}
# ------------------
>>> del dic # 删除字典本身
>>> dic
Traceback (most recent call last):File "<pyshell#20>", line 1, in <module>dic
NameError: name 'dic' is not defined
6、字典copy
python字典的copy( )函数返回一个字典的浅复制。 使用方式 dict.copy( )
>>> dict1 = {'Name': 'Jim', 'Age':9}
>>> dict2 = dict1.copy()
>>> dict2
{'Age': 9, 'Name': 'Jim'}
那么直接赋值和copy有什么区别呢?
dict1 = {'user':'runoob','num':[1,2,3]}dict2 = dict1 # 浅拷贝: 引用对象
dict3 = dict1.copy() # 浅拷贝:深拷贝父对象(一级目录),子对象(二级目录)不拷贝,还是引用# 修改 data 数据
dict1['user']='root'
dict1['num'].remove(1)# 输出结果
>>> print(dict1)
{'user': 'root', 'num': [2, 3]}
>>> print(dict2)
{'user': 'root', 'num': [2, 3]}
>>> print(dict3)
{'user': 'runoob', 'num': [2, 3]}
实例中 dict2 其实是 dict1 的引用(别名),所以输出结果都是一致的,dict3 父对象进行了深拷贝,不会随dict1 修改而修改,子对象是浅拷贝所以随 dict1 的修改而修改。 (而且注意python的运算规律)
更多见: Python 直接赋值、浅拷贝和深度拷贝解析
7、字典(Dictionary)的 fromkeys()方法
Python 字典 fromkeys() 函数用于创建一个新字典,以序列 seq 中元素做字典的键,value 为字典所有键对应的初始值。 语法: dict.fromkeys(seq[, value])
>>> seq = ('Google', 'Runoob', 'Taobao')
>>> dict = dict.fromkeys(seq)
{'Google': None, 'Taobao': None, 'Runoob': None}
>>> dict = dict.fromkeys(seq, 10)
{'Google': 10, 'Taobao': 10, 'Runoob': 10}
# fromkeys()的方法,只能赋唯一值给key。。。
>>> >>> dict = dict.fromkeys(seq,seq)
>>> dict
{'Google': ('Google', 'Runoob', 'Taobao'), 'Taobao': ('Google', 'Runoob', 'Taobao'), 'Runoob': ('Google', 'Runoob', 'Taobao')}
8、get(key)
get(key) # 返回指定键的值,如果键不在字典中,则返回default值
>>> dic = {'Name': 'Jack', 'Age': 7, 'Class': 'First'}
>>> dic.get('Name')
'Jack'
# 注意name 不是Name, 所以下面的访问不存在的name,没有报错,但不会显示None
>>> dic.get('name')
>>> dic['name']
Traceback (most recent call last):File "<stdin>", line 1, in <module>
KeyError: 'name'
9、items( )、keys( )、values( )
items( ) # 以列表返回可遍历的(键, 值) 元组对 keys( ) 以列表返回字典所有的键 values( ) 以列表返回字典所有的值
>>> dic = {'Name': 'Jack', 'Age': 7, 'Class': 'First'}
>>> dic.items()
dict_items([('Name', 'Jack'), ('Age', 7), ('Class', 'First')])
>>> dic.values()
dict_values(['Jack', 7, 'First'])
>>> dic.keys()
dict_keys(['Name', 'Age', 'Class'])
10、pop(key) 与popitem( )
pop(key) 删除并返回指定key的值
>>> dic = {'Name': 'Jack', 'Age': 7, 'Class': 'First'}
>>> a = dic.pop('Name')
>>> dic
{'Age': 7, 'Class': 'First'}
>>> a
'Jack'
popitem( ) 删除并返回字典的最后一个键值对,不接受参数。
>>> dic = {'Name': 'Jack', 'Age': 7, 'Class': 'First'}
>>> dic.popitem('Age')
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: popitem() takes no arguments (1 given)
>>> b = dic.popitem()
>>> dic
{'Name': 'Jack', 'Age': 7}
>>> b
('Class', 'First')
11、setdefault(key, default=None)
setdefault(key, default=None) 和get()类似,但如果键不存在于字典中,将会添加键并将值设为default
>>> dic = {'Name': 'Jack', 'Age': 7, 'Class': 'First'}
>>> dic.setdefault('id')
>>> dic
{'Name': 'Jack', 'Age': 7, 'Class': 'First', 'id': None}
>>> dic.setdefault('id',10) # 再次使用,改变不了键'id'的值了。
>>> dic
{'Name': 'Jack', 'Age': 7, 'Class': 'First', 'id': None}
>>> dic = {'Name': 'Jack', 'Age': 7, 'Class': 'First'}
>>> dic.setdefault('id',10)
10
>>> dic
{'Name': 'Jack', 'Age': 7, 'Class': 'First', 'id': 10}
12、update(dict2)
update(dict2) 把字典dict2的键/值对更新到dict里 (在list中使用extend)
>>> dic = {'Name': 'Jack', 'Age': 7, 'Class': 'First', 'id': 10}
>>> seq = {'Google': 10, 'Taobao': 10, 'Runoob': 10}
>>> dic.update(seq)
>>> dic
{'Name': 'Jack', 'Age': 7, 'Class': 'First', 'id': 10, 'Google': 10, 'Taobao': 10, 'Runoob': 10}
13、 遍历字典
从Python3.6开始遍历字典获得的键值对是有序的!
dic = {'Name': 'Jack', 'Age': 7, 'Class': 'First'}# 1 直接遍历字典获取键,根据键取值
>>> dic = {'Name': 'Jack', 'Age': 7, 'Class': 'First'}
>>> for key in dic:
... print(key, dic[key])
...
Name Jack
Age 7
Class First# 2 利用items方法获取键值,速度很慢,少用
>>> for key, value in dic.items():
... print(key,value)
...
Name Jack
Age 7
Class First#3 利用keys方法获取键
>>> for key in dic.keys():
... print(key, dic[key])
...
Name Jack
Age 7
Class First#4 利用values方法获取值,但无法获取对应的键。
>>> for value in dic.values():
... print(value)
...
Jack
7
First
14、 利用循环构造字典
# 比较经典的一种用法
>>> dic ={}
>>> for i in 'aefegd':
... dic[i] = ord(i)
...
>>> dic
{'a': 97, 'e': 101, 'f': 102, 'g': 103, 'd': 100}