Python的组合数据类型-字典

字典

字典 ( dictionary ) 采用 0 个或多个键值对(key-value)的形式存储数据。Python 对 key 进行哈希函数运算,根据计算的结果决定 value 的存储地址,所以是无序组合数据类型,且 key 必须是可哈希的。可哈希的 key 必须是不可变类型,如:数字、字符串、元组。

字典是除列表以外 Python 之中最灵活的内置数据结构类型。列表是有序的对象结合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。

字典是可变的,因此可以对其进行数据项的添加或移除操作。

注意: 从 Python 3.6 开始,字典的 Key 将会保留插入或声明时候的顺序,但并不是可以被排序的那种顺序。从 3.7 开始这成了正式的 Python 语言特性,3.6 改进的字典更节省内存,运行效率差不多,有一个 “副作用” 就是字典变成有序的了。

字典的创建

dict 数据类型可以作为函数调用:dict()——不带参数将返回一个空字典,带一个映射类型参数将返回以该参数为基础的字典。比如该参数本身为字典,则返回该参数的浅拷贝。使用序列型参数也是可以的,前提是序列中的每个数据项本身是一个包含两个对象的序列,其中第一个用作键,第二个用作值。

字典也可以使用花括号 {} 创建——空的 {} 会创建空字典,非空的 {} 必须包含一个或多个逗号分隔的项,其中每一项都包含一个键、一个字面意义的冒号以及一个值:

1
2
3
4
5
6
7
8
dic1 = {
'name' : 'Tom',
'age' : '18',
'sex' : 'male',
'hobby': 'Jerry'
}

dic1={'name':'Tom','age':18,'sex':'male','hobby':'Jerry'}

字典的操作

字典支持内置的 len() 函数,也可以使用 innot in 对其键进行快速的成员关系测试

方法

语法 表述
d.clear() 将字典d清空
d.copy() 返回字典d的浅拷贝
d.fromkeys(s,v) 返回一个字典,该字典的键为序列s的项,值为None或v(r如果给定了参数v)
d.get(k) 返回字典d中键k对应的值,如果k不在d中就返回None
d.get(k,v) 返回字典d中键k对应的值,如果k不在d中就返回预设值v
d.items() 返回字典d中所有 键-值 对的视图
d.keys() 返回字典d中所有的键的视图
d.values() 返回字典d中所有值的视图
d.pop(k) 移除键为k的项并返回键k对应的值,如果k不在d中就产生KeyError异常
d.pop(k,v) 移除键为k的项并返回键k对应的值,如果k不在d中就返回预设值v
d.popitem() 随机移除并返回字典d中的任意一个 键-值 对,如果d为空就产生KeyError异常
d.setdefault(k,v) 与d.get()类似,不同之处在于,如果键k不在d中就插入一个键为k的新值,其值为None或预设值v(如果给定了参数v)
d.update(a) 如果a中的键-值 对不存在d中就添加到d,如果a中的键在d中,就将a中的键对应的值替换掉d中键对应的值。a可以是字典,也可以是关键字参数

示例

增加元素,字典的键是独一无二的,因此如果向字典中添加一个键-值项,并且该键与字典中现存的某个键相同,那么实际的效果是使用新值替换该键的现值。

1
2
3
4
5
6
7
8
9
10
11
12
dic1 = {}
dic1['name'] = 'Tom'
dic1['age'] = 18
print(dic1) # {'name': 'Tom', 'age': 18}

a = dic1.setdefault('name', 'Jerry')
b = dic1.setdefault('age', 22)
# 如果 key 存在则不做更改,返回对应字典中相应的 key 对应的 value
# 如果 key 不存在则在字典中增加新的 key-value 对,并返回相应的 value

print(a, b) # Tom 18
print(dic1) # {'name': 'Tom', 'age': 18}

查找元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
dic1 = {'name': 'Tom', 'age': 18, 'sex': 'male', 'hobby': 'Jerry'}

print(dic1['name']) # Tom
print(dic1.get('age', False)) # 18
print(dic1.get('son', 'little jerry')) # little jerry
print(dic1.get('ages', False)) # False
# 指定的键对应的值不存在,则使用指定的默认值,否则返回实际的值

print(list(dic1.keys())) # ['name', 'age', 'sex', 'hobby']
# 查看 key 的列表

print(list(dic1.values())) # ['Tom', 18, 'male', 'Jerry']
# 查看 value 的列表

print(list(dic1.items()))
# [('name', 'Tom'), ('age', 18), ('sex', 'male'), ('hobby', 'Jerry')]
# 查看所有的 key-value 对

修改数据

1
2
3
4
5
6
7
8
9
10
11
12
13
dic1 = {'name': 'Tom', 'age': 18, 'sex': 'male', 'hobby': 'Jerry'}
print(dic1)
# {'name': 'Tom', 'age': 18, 'sex': 'male', 'hobby': 'Jerry'}

dic1['name'] = 'Jerry'
print(dic1)
# {'name': 'Jerry', 'age': 18, 'sex': 'male', 'hobby': 'Jerry'}

dic2 = {'sex': 'male', 'hobby': 'girl', 'age': 36}
dic1.update(dic2)
# 如果两个字典中存在相同的 key ,则在使用 update 时将会更新相应的 key 对应的 value ,否则将 key-value 对加入字典
print(dic1)
# {'name': 'Jerry', 'age': 36, 'sex': 'male', 'hobby': 'girl'}

删除

1
2
3
4
5
6
7
8
9
10
11
12
13
dic1 = {'name': 'Tom', 'age': 18, 'sex': 'male', 'hobby': 'Jerry'}

# 删除指定的 key-value 对
del dic1['name']

dic1.pop('age') # 删除并返回该 key-value 的值
dic1.popitem() # 随机删除某组 key-value 对,并以元组方式返回值

# 清空整个字典
dic1.clear()

# 删除整个字典
del dic1

其他操作:

dict.fromkeys

1
2
3
4
5
6
7
d1 = dict.fromkeys(['host1', 'host2', 'host3'], 'Mac')
print(d1)
# {'host1': 'Mac', 'host2': 'Mac', 'host3': 'Mac'}

d1['host2'] = 'abc'
print(d1)
# {'host1': 'Mac', 'host2': 'abc', 'host3': 'Mac'}

字典的嵌套

1
2
3
4
5
6
7
province_city = {
'河北': {
'石家庄': ['长安区', '桥东区', '桥西区', '新华区', '井陉矿区', '裕华区', '井陉县', '正定县', '栾城县', '行唐县', '灵寿县', '高邑县', '深泽县', '赞皇县', '无极县', '平山县', '元氏县', '赵县', '辛集市', '藁城市', '晋州市', '新乐市', '鹿泉市', '其他'],
'唐山': ['路南区', '路北区', '古冶区', '开平区', '丰南区', '丰润区', '滦县', '滦南县', '乐亭县', '迁西县', '玉田县', '唐海县', '遵化市', '迁安市', ' 曹妃甸区', '其他'],
'秦皇岛': ['海港区', '山海关区', '北戴河区', '青龙满族自治县', '昌黎县', '抚宁县', '卢龙县', '其他']
}
}

sorted(dict) : 返回一个有序的包含字典所有 key 的列表 。

1
2
3
4
5
6
7
8
9
dic = {5: '555', 2: '666', 4: '444'}
print(sorted(dic))
# [2, 4, 5]

print(sorted(dic.values()))
# ['444', '555', '666']

print(sorted(dic.items()))
# [(2, '666'), (4, '444'), (5, '555')]

字典的遍历

字典的 itmes 指的是键值对,在遍历的时候存在一个转换过程,因此如果数据量大的情况下效率比较低,不建议采用这种方法迭代,而建议使用 for k in dic: 的方法遍历。

1
2
3
4
5
6
7
8
9
dic5={'name': 'tom', 'age': 18}

for key in dic5:
print(key,dic5[key])

for items in dic5.items():
print(items)
for keys,values in dic5.items():
print(keys,values)

判断字典中有没有某个 key

要判断字典中是否有某个键 k,一般使用 dic.get('k') 的方法来实现。

1
2
3
4
5
6
7
8
9
10
>>> dic = {'name': 'Jerry', 'sex': 'male'}
>>> dic.get('name')
'Jerry'
>>> if dic.get('name'):
... print('"name" is in dict dic')
... else:
... print('"name" is not in dict dic')
...
"name" is in dict dic
>>>

但是如果字典中的键 k 所对应的值是 None 的时候就会出现严重的问题,这时候就会认为没有这个键 k。例如:

1
2
3
4
5
6
7
8
9
>>> dic = {'name': 'Jerry', 'sex': 'male', 'hobby': None}
>>> dic.get('hobby')
>>> if dic.get('hobby'):
... print('"hobby" is in dict dic')
... else:
... print('"hobby" is not in dict dic')
...
"hobby" is not in dict dic
>>>

为了避免这种情况影响到程序的判断,应该使用成员判断操作符 in 的方法。

1
2
>>> "hobby" in dic
True

但是多数情况下除了判断字典中是否有对应的键,还有可能需要操作键所对应的值。所以,使用 for k in dic: 的方法遍历字典是最为合适的。

1
2
3
4
5
6
7
8
9
>>> dic = {'name': 'Jerry', 'sex': 'male', 'hobby': None}
>>> for k in dic:
... if dic[k]:
... pass
... else:
... dic[k] = 'study'
...
>>> dic
{'name': 'Jerry', 'sex': 'male', 'hobby': 'study'}
有钱任性,请我吃包辣条
0%