ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Python 数据结构的本质:位置、对象引用、Hash 与可变性

Python 数据结构的本质:位置、对象引用、Hash 与可变性 Python 中不同的数据类型虽然都可以保存数据但它们管理数据的方式并不一样。真正需要理解的是这个数据结构靠什么找到和管理里面的数据1. List按照位置管理元素lst[10,20,30]可以理解为位置 0 → 10 位置 1 → 20 位置 2 → 30所以可以lst[1]得到20也可以lst[1]100变成[10,100,30]因此list 按位置管理元素每个位置都可以重新指向其他对象。2. Tuple位置存在但位置指向的对象不能更换t(10,20,30)同样可以理解为位置 0 → 10 位置 1 → 20 位置 2 → 30所以可以t[1]但不能t[1]100因为 tuple 创建以后每一个位置所指向的对象不能再被换掉。但是t(10,[20,30])是允许的。此时位置 0 → 10 位置 1 → [20, 30]可以t[1].append(40)得到(10,[20,30,40])因为t[1]仍然指向原来的 list只是 list 自己内部的数据发生了变化。因此tuple 的不可变是位置所指向的对象不能更换并不代表被指向的对象本身一定不能变化。3. Set按照 Hash 管理成员s{10,20,30}set 没有s[0]因为 set 不是按照位置来管理元素。元素加入 set 时Python 会元素 → 计算 hash → 根据 hash 计算内部存储位置 → 存入 set例如10 → hash(10) → 计算位置 → 存放 10 20 → hash(20) → 计算位置 → 存放 20 30 → hash(30) → 计算位置 → 存放 30查询20ins大致过程20 → 计算 hash(20) → 根据 hash 找到可能的位置 → 检查是不是 20 → 返回 True / False所以set 时按照 hash 管理成员而不是按下标管理元素。这也是为什么 set 中的元素必须可以被hash()。例如hash(10)# 可以hash(hello)# 可以所以它们可以放入 set。而hash([1,2])会报错TypeError: unhashable type: list因此 list 不能直接作为 set 的元素。4. DictKey 按照 Hash 管理Value 跟着 Key 保存d{name:Tom,age:20}dict 不是按照第 0 个 第 1 个来查找数据。它主要根据key 的 hash管理数据。例如d[name]Python 大致会name → 计算 hash(name) → 根据 hash 找到内部位置 → 找到 key name → 得到对应的 value Tom所以字典内部管理的是key value其中key 负责定位value 跟着 key 保存。因此字典的 key 必须可哈希{name:Tom,# str 可以10:hello# int 可以}但不能{[1,2]:hello}因为 list 不可哈希。而 value 没有这个限制d{data:[1,2,3]}完全可以。因为真正用来定位的是data而不是后面的 list。5. String按照位置读取字符但字符串本身不能修改sPython-DuDu可以理解为位置 0 → P 位置 1 → y 位置 2 → t 位置 3 → h 位置 4 → o 位置 5 → n所以可以s[0]得到P但是不能s[0]J因为字符串是不可变的。如果写sDuDu并不是把原来的Python修改成DuDu。而是让变量s改去指向新的字符串对象。因此str 按照位置读取但字符串创建以后内容不能修改。字符串也是可哈希的hash(Python)所以字符串可以作为set 元素 dict 的 key6. 为什么 List、Dict、Set 本身不能 Hash它们都有一个共同特点自身内容可以直接发生变化。例如lst.append(10)d[age]30s.add(40)如果这种对象作为哈希表中的元素或 key而它们的内容变化又导致 hash 发生变化就可能导致存进去时使用一个 hash 后来查找时变成另一个 hash这样原来的位置就可能找不到。所以 Python 将常见的list dict set设计成不可哈希。7. 常见类型总结类型主要管理方式是否可修改是否可 Hashlist按位置管理元素是否tuple按位置管理位置所指向的对象不能更换否内部所有元素都可 Hash 时可以set根据元素的 Hash 计算内部存储和查找位置是set本身不可以dict根据 Key 的 Hash 计算内部存储和查找位置是dict本身不可以str按位置读取字符否可以int单个不可变值否可以frozenset根据元素的 Hash 计算内部存储和查找位置否可以核心理解list → 按位置管理 → 位置可以重新指向其他对象 tuple → 按位置管理 → 每个位置指向的对象不能更换 set → 按 hash 管理成员 → 没有下标 dict → 按 key 的 hash 管理数据 → key 负责定位value 跟随 key 保存 str → 按位置读取字符 → 但字符不能直接修改最终可以记住一句List 和 Tuple 重点是“位置”Set 重点是“成员 Hash”Dict 重点是“Key Hash”String 有位置但自身不可修改。
返回列表