dict
Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。
| |
为什么dict查找速度这么快?因为dict的实现原理和查字典是一样的。假设字典包含了1万个汉字,我们要查某一个字,一个办法是把字典从第一页往后翻,直到找到我们想要的字为止,这种方法就是在list中查找元素的方法,list越大,查找越慢。
第二种方法是先在字典的索引表里(比如部首表)查这个字对应的页码,然后直接翻到该页,找到这个字。无论找哪个字,这种查找速度都非常快,不会随着字典大小的增加而变慢。
dict就是第二种实现方式,给定一个名字,比如'Michael',dict在内部就可以直接计算出Michael对应的存放成绩的“页码”,也就是95这个数字存放的内存地址,直接取出来,所以速度非常快。
把数据放入dict的方法,除了初始化时指定外,还可以通过key放入:
| |
由于一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉:
| |
通过in判断key是否存在
| |
二是通过dict提供的get()方法,如果key不存在,可以返回None,或者自己指定的value:
| |
要删除一个key,用pop(key)方法,对应的value也会从dict中删除:
| |
dict内部存放的顺序和key放入的顺序是没有关系的。
和list比较,dict有以下几个特点:
- 查找和插入的速度极快,不会随着key的增加而变慢;
- 需要占用大量的内存,内存浪费多。
而list相反:
- 查找和插入的时间随着元素的增加而增加;
- 占用空间小,浪费内存很少。
dict是用空间来换取时间的一种方法
第一条就是dict的key必须是不可变对象
set
set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key
| |
通过add(key)方法可以添加元素到set中,可以重复添加,但不会有效果
| |
通过remove(key)方法可以删除元素
注:无法使用s.pop
| |
set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:
| |
set和dict的唯一区别仅在于没有存储对应的value,但是,set的原理和dict一样,所以,同样不可以放入可变对象,因为无法判断两个可变对象是否相等
为了保证 dict 和 set 能快速、准确地找到数据,它们要求钥匙(key)必须是绝对不可变**的 。
整理了关于 dict 和 set 的详细对比及操作表格:
1. dict 与 set 的核心概念对比
这两者在 Python 中都是非常高效的数据结构,但用途有所不同:
| 特性 | dict (字典) | set (集合) |
|---|---|---|
| 定义 | 使用 键-值 (key-value) 存储,具有极快的查找速度 [1]。 | 一组 key 的集合,但不存储 value [2]。 |
| 重复性 | 一个 key 只能对应一个 value,多次赋值会覆盖旧值 [3]。 | key 不能重复,重复元素会自动被过滤 [2, 4]。 |
| 有序性 | 内部存放顺序和 key 放入的顺序无关 [2]。 | 无序,显示的顺序不代表内部实际顺序 [4]。 |
| 对 Key 的要求 | 必须是 不可变对象(如字符串、整数)[2]。 | 同样必须是 不可变对象,不能放入 list 等 [4]。 |
| 主要用途 | 快速根据 key 查找对应的 value [1]。 | 数学意义上的去重、交集、并集运算 [4]。 |
2. dict 与 set 的常用操作方法
下表列出了文中提到的主要操作方式:
| 操作类型 | dict (字典) | set (集合) |
|---|---|---|
| 初始化/创建 | d = {'Michael': 95, 'Bob': 75} [1] | s = {1, 2, 3} 或 set([5-7]) [2, 4] |
| 添加/修改 | d['Adam'] = 67 [3] | s.add(4) [4] |
| 查找/判断是否存在 | key in d 或 d.get(key) [3] | key in s (原理同 dict) |
| 删除元素 | d.pop(key) [3] | s.remove(key) [4] |
| 特殊运算 | —— | 交集 s1 & s2,并集 `s1 |
3. dict 与 list 的性能对比(空间换时间)
源码中明确对比了 dict(哈希表原理)和 list(顺序查找)的差异 [2]:
| 特性 | dict | list |
|---|---|---|
| 查找和插入速度 | 极快,不会随 key 增加而变慢 [2]。 | 随着元素增加,耗时越来越长 [2]。 |
| 内存占用 | 较大,需要占用大量内存,浪费多 [2]。 | 占用空间小,浪费内存很少 [2]。 |
| 结论 | 用空间换取时间的方法 [2]。 | 适合数据量小、对内存敏感的场景。 |
💡 重要提醒:关于“不可变对象”
无论是 dict 的 key 还是 set 的元素,都必须使用 不可变对象 [2, 4]。
可以放入: 字符串 (
str)、整数 (int)、全由不可变对象组成的元组 (tuple) [2, 8]。不可以放入: 列表 (
list),因为它是可变的,无法计算固定的哈希值,会导致报错 [2, 4]。
在 Python 中,花括号 {} 和圆括号 () 分别代表了不同的数据结构,其核心区别在于功能用途和可变性:
1. 花括号 {}:用于 dict 和 set
在源码中,花括号主要有两种用途:
- dict(字典): 采用 “键-值对”(key-value) 的形式存储数据 [1]。
- 写法:
d = {'Michael': 95, 'Bob': 75}[1, 2]。 - 特点: 查找速度极快,不会随元素增加而变慢,但占用内存较多 [1, 3]。
- 写法:
- set(集合): 是一组 key 的集合,但不存储 value [3]。
- 写法:
s = {1, 2, 3}[3]。 - 特点: 元素不重复(自动过滤重复项),且内部元素是无序的 [4]。
- 写法:
2. 圆括号 ():用于 tuple
圆括号在源码中被用来表示 tuple(元组)。
- tuple(元组): 一种不可变的有序列表 [5]。
- 写法:
t = (1, 2, 3)[5]。 - 特点: 一旦初始化就不能修改。因为它是不可变的,所以安全性更高 [5]。
- 写法:
3. 核心区别汇总
| 特性 | 花括号 {} (dict/set) | 圆括号 () (tuple) |
|---|---|---|
| 数据类型 | dict 或 set [1, 3] | tuple [5] |
| 存储内容 | dict 存键值对,set 只存键 [1, 3] | 存储有序的元素序列 [5] |
| 重复性 | key 不允许重复(set 会去重)[3, 4] | 允许元素重复 |
| 有序性 | 无序(存放顺序与放入顺序无关)[3, 4] | 有序 [5] |
| 可变性 | dict 和 set 本身是可变的(可添加删除)[2, 4] | tuple 是不可变对象 [5] |
