有没有做头像的网站厦门人才网唯一官网
原理
Python中的字典(Dictionary)是一种基于哈希表(Hash Table)的实现,提供了高效的键值对(Key-Value Pair)存储和访问机制。了解字典的工作原理有助于更好地理解其性能特性以及为什么在某些情况下使用字典会非常高效。
哈希表的基本原理
-
哈希函数:哈希表依赖于哈希函数来将键(Key)转换为存储位置的索引。理想情况下,哈希函数应该将不同的键均匀分布到哈希表的地址空间中,以减少冲突(两个键映射到同一位置)的可能性。
-
键的唯一性:在字典中,键必须是唯一的。如果尝试使用已存在的键来存储新的值,旧的值将被新的值覆盖。
-
冲突解决:当两个键映射到同一个位置时,会发生冲突。Python字典使用开放寻址法(Open Addressing)和二次探测(Quadratic Probing)等技术来解决冲突。
字典的性能特性
-
时间复杂度:对于大多数操作(包括查找、插入和删除),Python字典的平均时间复杂度为O(1)。然而,在最坏的情况下(例如,当哈希函数导致大量冲突时),这些操作的时间复杂度可能会恶化到O(n)。但是,通过使用良好的哈希函数和动态调整哈希表的大小,Python尽量保证字典操作的高效性。
-
动态调整大小:当字典中的元素数量增加,导致装载因子(存储的元素数量与哈希表大小的比值)超过某个阈值时,Python会增加哈希表的大小并重新哈希所有的键。这个过程称为“重新哈希”(Rehashing),虽然会暂时增加操作的开销,但可以保持字典操作的长期效率。
字典的特性
-
无序:在Python 3.6中,字典的有序性首次作为CPython实现的一个细节被引入,虽然它在实践中确实是有序的,但当时官方并不保证所有Python实现都会有这个特性。从3.7版本开始,这一特性成为了Python语言的官方规范的一部分,因此在所有遵循该规范的Python实现中,字典都是有序的。
这一变化使得在需要维护元素顺序的情况下,开发者不再需要使用
collections.OrderedDict
,因为普通的dict
已经可以满足需求。这不仅简化了代码,也改善了性能,因为标准的dict
类型在Python 3.7及更高版本中被优化以更高效地存储和访问元素。-
验证
# 创建一个空字典 ordered_dict = {}# 向字典中添加一些键值对 ordered_dict['banana'] = 1 ordered_dict['apple'] = 2 ordered_dict['pear'] = 3 ordered_dict['orange'] = 4# 打印字典中的项,查看是否按插入顺序输出 for key in ordered_dict:print(key, ordered_dict[key])# 创建两个具有相同键值对但插入顺序不同的字典 dict1 = {'a': 1, 'b': 2, 'c': 3} dict2 = {'b': 2, 'a': 1, 'c': 3}# 比较字典 print(dict1) print(dict2) print(dict1 == dict2) # 输出: True
-
尽管
dict1
和dict2
的插入顺序不同,但它们被认为是相等的,因为它们包含相同的键值对。这证明了字典的比较不考虑键值对的插入顺序,但字典本身在内部是维护了插入顺序的。
-
-
键的数据类型:作为键的对象必须是不可变的,比如整数、浮点数、字符串、元组。这是因为只有不可变对象才能保证在整个生命周期中哈希值不变,从而保持字典的完整性。
了解这些原理有助于开发者更有效地使用Python字典,尤其是在处理大量数据和对性能有较高要求的场景中。
操作
Python 中的字典(dict
)是一种可变容器模型,可以存储任意类型对象,如字符串、数字、元组等。字典中的每个元素都是一个键值对。这里介绍一些基本的字典操作:
创建字典
# 空字典
my_dict = {}# 带有数据的字典
my_dict = {'name': 'John', 'age': 30, 'city': 'New York'}
访问元素
print(my_dict['name']) # 输出: John# 使用 get 方法,如果键不存在返回 None 而不是抛出异常
print(my_dict.get('age')) # 输出: 30
添加或修改元素
# 添加新键值对
my_dict['email'] = 'john@example.com'# 修改已有键的值
my_dict['age'] = 31
删除元素
# 删除特定的键值对,使用 del 关键词:
del my_dict['city']# 使用 pop 方法删除并返回被删除值:
removed_value = my_dict.pop('email')
print(removed_value) # 输出被删除的值:john@example.com# 清空整个字典:
my_dict.clear()
检查键是否存在
if 'name' in my_dict:print("Name is present in the dictionary")
遍历字典
遍历所有键:
for key in my_dict.keys():print(key)
遍历所有值:
for value in my_dict.values():print(value)
同时遍历键和值:
for key, value in my_dict.items():print(key, value)
字典长度
获取包含多少个键值对:
len(my_dict)
复制一个字典
创建当前字典的浅拷贝:
new_mydict = my_dic.copy()或者使用 dict() 函数:
new_mydict2 = dict(my_dic)
以上就是 Python 字典中常用操作。Python 的 dict
类型提供了丰富而强大的方法来处理映射关系,并且由于其底层实现为哈希表,因此在访问和添加数据时具有非常高效率。
高级操作
Python 字典的高级操作涉及更复杂的数据处理和字典操作技巧。以下是一些有用的高级字典操作:
字典推导式
字典推导式(Dictionary Comprehension)是一种简洁地创建字典的方法,类似于列表推导式。
# 通过键值对序列创建字典
keys = ['name', 'age', 'city']
values = ['John', 30, 'New York']my_dict = {k: v for k, v in zip(keys, values)}
print(my_dict) # 输出: {'name': 'John', 'age': 30, 'city': 'New York'}
合并两个字典
在 Python 3.5+ 中,可以使用 {**d1, **d2}
的语法合并两个字典。在 Python 3.9+ 中,还可以使用 |
操作符,表达式中后出现的字典中的键值对将覆盖先前字典中的键值对。
dict1 = {'name': 'John', 'age': 30}
dict2 = {'city': 'New York', 'email': "john@example.com"}merged_dict = {**dict1, **dict2}
# 或者在 Python 3.9+
merged_dict_39 = dict1 | dict2print(merged_dict)
使用 collections.defaultdict
Python中的defaultdict
和普通的dict
都是字典类型,用于存储键值对。但是,它们之间有一个主要的区别:
当你试图访问dict
中不存在的键时,Python会抛出一个KeyError
。但是,如果你使用defaultdict
,并试图访问一个不存在的键,它会首先为这个键生成一个默认值,然后返回这个默认值。这个默认值是通过传递给defaultdict
的default_factory
函数生成的。
from collections import defaultdictddict = defaultdict(list)# 当尝试访问不存在的键时,默认初始化为空列表,并不会抛出 KeyError 异常。
ddict['a'].append(1)
ddict['a'].append(2)
print(ddict) # 输出: defaultdict(<class ‘list’>, {'a': [1, 2]})# 创建一个默认值为int的defaultdict
d = defaultdict(int)
# 访问一个不存在的键
print(d['key']) # 输出 0
# 当我们试图访问不存在的键 'key' 时,`defaultdict`首先调用`int()`(没有任何参数)来生成一个默认值(0),然后返回这个值。
这个特性使得defaultdict
在某些情况下非常有用,例如,当你需要一个字典来存储列表,且希望所有的键都默认关联一个空列表时,你可以使用defaultdict(list)
。
使用fromkeys生成默认值的新字典
fromkeys()
是一个类方法,用于创建一个新字典,其中包含指定的键,每个键对应的值都是相同的初始值。这个方法通常用于初始化字典。
基本语法:
dict.fromkeys(seq[, value])
seq
:键列表。value
:可选参数,所有键对应的初始值,默认为 None。
示例:
# 使用 fromkeys 创建一个新字典,所有键的初始值为 None
new_dict = dict.fromkeys(['a', 'b', 'c'])
print(new_dict) # 输出: {'a': None, 'b': None, 'c': None}# 使用 fromkeys 创建一个新字典,并设置所有键的初始值为 0
new_dict_with_value = dict.fromkeys(['x', 'y', 'z'], 0)
print(new_dict_with_value) # 输出: {'x': 0, 'y': 0, 'z': 0}
这种方式非常适合快速初始化具有固定或默认值的字典。
使用 collections.OrderedDict
从 Python 3.7 开始,所有普通的 dict 都保持插入顺序。但是,在早期版本中或者当需要依赖顺序相关功能时(如移动元素到末尾),可以使用 OrderedDict
。
from collections import OrderedDictodict = OrderedDict([('name', 'John'), ('age', 30)])
odict['city'] = "New York" # 添加到末尾
print(odict) # 输出: OrderedDict([('name', ‘John’), ('age’, 30), ('city’, ‘New York')])
使用 zip()
合并键和值列表为字典
如果你有两个分别代表键和值的列表,你可以使用 zip()
函数轻松合并它们为一个字典。
keys_list = ["a", "b", "c"]
values_list =[1, 2, 3]combined_dict= dict(zip(keys_list , values_list))
print(combined_dict) # 输出:{'a’:1,'b’:2,'c’:3}
更新或添加多个元素
使用 .update()
方法更新或添加多个键值对。原本字典存在的值仍然保留
my_dict.update({'email':'john_new@example.com','country':'USA'})
这些高级操作使得处理复杂数据结构、合并数据以及进行各种转换变得更加简单有效。掌握这些技巧能够帮助你编写更加简洁、高效且易于维护的代码。
与json格式相似
相似
Python的字典和JSON(JavaScript Object Notation)非常相似,因为它们都是键值对的集合,这种数据结构在许多编程语言中都很常见。这种结构非常灵活,可以用来存储和表示各种复杂的数据类型。
JSON是一种数据交换格式,它的语法来源于JavaScript的对象字面量语法,但它是语言无关的,可以被许多编程语言(包括Python)读取和生成。JSON的数据格式和Python的字典非常相似,这使得在Python中处理JSON数据非常方便。
Python的json
模块提供了一种简单的方式来编码和解码JSON数据。例如,你可以使用json.dumps()
函数将一个Python字典转换为一个JSON字符串,或者使用json.loads()
函数将一个JSON字符串解析为一个Python字典。
区别
尽管Python的字典和JSON有很多相似之处,但它们也有一些重要的区别。例如,Python的字典可以包含各种类型的键,包括不可变类型(如整数和元组)和可变类型(如列表),而JSON的键必须是字符串。此外,Python的字典可以包含任何Python对象作为值,而JSON的值只能是一种基本数据类型(如字符串、数字、布尔值、null、数组或另一个JSON对象)。
转换
在Python中,字典和JSON之间的转换可以通过json
模块来实现。
将字典转换为JSON字符串(序列化):
dumps()
方法用于将Python对象编码成 JSON 字符串。loads()
方法用于解码 JSON 数据。该方法返回 Python 字段的数据类型。
import json# 假设dict_obj是一个Python字典
dict_obj = {'name': 'John', 'age': 30, 'city': 'New York'}# 将字典转换为JSON字符串
json_str = json.dumps(dict_obj)print(json_str) # 输出:{"name": "John", "age": 30, "city": "New York"}
将JSON字符串转换为字典(反序列化):
import json# 假设json_str是一个JSON格式的字符串
json_str = '{"name": "John", "age": 30, "city": "New York"}'# 将JSON字符串转换回Python字典
dict_obj = json.loads(json_str)print(dict_obj) # 输出:{'name': 'John', 'age': 30, 'city': 'New York'}
特别注意!!!
1、别使用错方法,dumps()和dump() 是两个方法,dump()只传一个参数会报错
Traceback (most recent call last):File "/Users/fangyirui/PycharmProjects/pythonProject/11 字典.py", line 31, in <module>json.dump(dic)
TypeError: dump() missing 1 required positional argument: 'fp'
错误信息表明json.dump()
函数缺少一个必需的位置参数'fp'
。在Python的json
模块中,dump()
方法用于将Python对象编码成JSON格式并写入到一个文件中。因此,它需要两个主要参数:
- 要序列化的Python对象(例如字典)。
- 一个
.write()
支持的file-like对象,即可以是打开文件进行写操作的文件句柄。
如果你想将字典保存为JSON到文件中,应该这样做:
import json# 假设dic是你想要序列化的字典
dic = {'name': 'John', 'age': 30, 'city': 'New York'}# 打开一个文件用于写入,并确保使用utf-8编码以支持多语言内容
with open('output.json', 'w', encoding='utf-8') as f:# 使用dump()方法将字典保存到刚才打开的文件里json.dump(dic, f)
这段代码会创建(或覆盖)名为"output.json" 的文件,并将 dic
字典以JSON格式写入该文件。
2、python字段的True布尔类型和"true"字符串类型转成json会导致格式错乱
dic = {'Alice': '23dsq41', True: '9102', 98.6: '3258'}
dic["true"] = "字符串"
print(dic) # {'Alice': '23dsq41', True: '9102', 98.6: '3258', 'true': '字符串'}
json_str_2 = json.dumps(dic)
print(json_str_2) # {"Alice": "23dsq41", "true": "9102", "98.6": "3258", "true": "\u5b57\u7b26\u4e32"}
因为python的布尔类型True转成json是"true",如果要确保不丢失数据,请避免使用可以导致重复关键字(经过类型强制之后) 的原始关键字。
当json解析回字典时,后面的相同的key值会覆盖前面的值,且key都是字符串类型
# 解析json
{"Alice": "23dsq41", "true": "9102", "98.6": "3258", "true": "\u5b57\u7b26\u4e32"}# 结果
dict =
{'Alice': '23dsq41', 'true': '字符串', '98.6': '3258'}
3、编码问题
在JSON中,非ASCII字符(比如中文字符)默认会被转换为Unicode转义序列。这是为了确保JSON字符串在各种环境下都能正确地被解析和显示,特别是在不同的编码系统之间传输数据时。
{"Alice": "23dsq41", "98.6": "3258", "true": "\u5b57\u7b26\u4e32"}
其中的 \u5b57\u7b26\u4e32
是“字符”两个字的Unicode编码。\u5b57
对应于“字”,\u7b26
对应于“符”。
如果你希望在使用 json.dumps()
方法将Python对象转换成JSON字符串时保持非ASCII文字(如中文)不被转义,可以通过设置 ensure_ascii=False
参数来实现:
import jsondict_obj = {'Alice': '23dsq41', '98.6': '3258', 'true': '字符串'}
json_str = json.dumps(dict_obj, ensure_ascii=False)print(json_str)
输出将会是:
{"Alice": "23dsq41", "true": "字符串", "98.6": "3258"}