Python 中主要数据类型分类及特性总结(附:可哈希 (Hashable) 与 不可哈希 (Unhashable) 详解)

张开发
2026/4/18 3:07:07 15 分钟阅读

分享文章

Python 中主要数据类型分类及特性总结(附:可哈希 (Hashable) 与 不可哈希 (Unhashable) 详解)
本文系统总结了Python中的数据类型分类及特性。主要内容包括数据类型分类基本类型int/float/str等、序列类型list/tuple/range、映射类型dict、集合类型set/frozenset和二进制序列类型bytes/bytearray类型特性对比可变性list/dict可变tuple/str不可变、有序性list有序set无序和可哈希性可哈希类型可作为字典键可哈希性详解定义了可哈希对象的条件不可变、有哈希值、可比较相等列举了常见可哈希与不可哈希类型并说明了可哈希性的实际应用场景类型转换与判断方法。全文通过对比表格和示例代码清晰展示了Python数据类型的核心特性与使用要点。Python 中主要数据类型分类总结一、基本数据类型类型名称示例特点可变性int整数42,-10,0b1010任意精度无范围限制不可变float浮点数3.14,-0.5,1.2e-5双精度浮点数不可变complex复数34j,1.2-0.5j实部虚部不可变bool布尔型True,False只有两个值是int子类不可变str字符串Hello,Python,多行Unicode字符序列不可变NoneType空值None表示空或不存在的值不可变二、序列类型类型名称示例特点可变性有序性list列表[1, 2, 3],[a, b]可存放任意类型功能强大可变有序tuple元组(1, 2, 3),(a,)轻量级不可变序列不可变有序range范围range(5),range(1,10,2)整数序列节省内存不可变有序三、映射类型类型名称示例特点可变性有序性dict字典{name:Tom, age:18}键值对存储键必须可哈希可变Python3.7有序四、集合类型类型名称示例特点可变性有序性set集合{1, 2, 3},set([1,2,2])元素唯一去重可变无序frozenset冻结集合frozenset([1,2,3])不可变版本的集合不可变无序五、二进制序列类型类型名称示例特点可变性bytes字节串bhello,bytes([65,66])0-255的整数序列不可变bytearray字节数组bytearray(bhello)可修改的字节序列可变memoryview内存视图memoryview(bhello)直接访问内存数据可变六、各类型对比速查可变 vs 不可变可变类型 (Mutable)不可变类型 (Immutable)listintdictfloatsetboolbytearraystr自定义类实例默认tuplefrozensetbytesrange有序 vs 无序有序类型 (Ordered)无序类型 (Unordered)listsettuplefrozensetstrdict(Python3.7前)rangedict(Python3.7)可哈希 vs 不可哈希可哈希类型可作为字典键不可哈希类型int,float,boolliststrdicttuple元素都哈希setfrozensetbytearrayNone七、类型判断与转换操作示例说明类型判断isinstance(5, int)推荐使用支持继承类型判断type(5) is int精确判断不考虑继承类型转换list((1,2,3))元组转列表类型转换tuple([1,2,3])列表转元组类型转换set([1,2,2,3])列表转集合去重类型转换dict([(1,a),(2,b)])键值对序列转字典类型转换str(123)转字符串类型转换int(123)字符串转整数八、各类型字面量速查类型字面量示例int42,0xFF十六进制,0o12八进制,0b1010二进制float3.14,1.2e-5complex34jstr单引号,双引号,三单引号,三双引号list[1, 2, 3]tuple(1, 2, 3)或1, 2, 3dict{key: value}set{1, 2, 3}boolTrue,FalseNoneNone提示Python 是动态强类型语言变量无需声明类型但不同类型之间通常不会自动转换。可哈希 (Hashable) 与 不可哈希 (Unhashable) 详解一、什么是哈希哈希是将任意大小的数据如字符串、数字通过哈希函数转换成固定长度的唯一标识哈希值的过程。python# 哈希值示例 hash(42) # 输出: 42 hash(hello) # 输出: -2091548855179221912 hash((1,2,3)) # 输出: 529344067295497451二、可哈希类型的特征一个对象是可哈希的需要满足以下条件✅有哈希值- 实现__hash__()方法✅可比较相等- 实现__eq__()方法✅不可变- 创建后内容不能改变三、常见可哈希与不可哈希类型类型可哈希原因int✅ 是不可变float✅ 是不可变bool✅ 是不可变str✅ 是不可变tuple✅ 是不可变前提内部元素也都可哈希frozenset✅ 是不可变None✅ 是单例对象list❌ 否可变内容可改变dict❌ 否可变set❌ 否可变bytearray❌ 否可变四、为什么需要可哈希可哈希对象可以作为字典的键(dict key)作为集合的元素(set element)python# ✅ 正确使用可哈希类型作为字典键 d { 1: 整数键, # int 可哈希 name: 字符串键, # str 可哈希 (1,2): 元组键 # tuple 可哈希 } # ✅ 正确使用可哈希类型作为集合元素 s {1, 2, 3, a, (4,5)} # ❌ 错误使用不可哈希类型作为字典键 d {[1,2]: 列表键} # TypeError: unhashable type: list # ❌ 错误使用不可哈希类型作为集合元素 s {[1,2], [3,4]} # TypeError: unhashable type: list五、特殊情况元组的可哈希性元组本身不可变但它的可哈希性取决于内部元素python# ✅ 元组内都是可哈希元素 → 元组可哈希 t1 (1, 2, a) hash(t1) # 成功 # ❌ 元组内包含不可哈希元素 → 元组不可哈希 t2 (1, [2, 3], a) hash(t2) # TypeError: unhashable type: list六、如何判断对象是否可哈希python# 方法1使用 hash() 函数测试 def is_hashable(obj): try: hash(obj) return True except TypeError: return False print(is_hashable(42)) # True print(is_hashable(hello)) # True print(is_hashable([1,2])) # False print(is_hashable({1,2})) # False # 方法2使用 collections.abc.Hashable from collections.abc import Hashable print(isinstance(42, Hashable)) # True print(isinstance([1,2], Hashable)) # False七、实际应用场景场景1去重时的问题pythondata [1, 2, 2, [3,4], [3,4], 5] # ❌ 错误直接对包含列表的列表用 set() 去重 unique set(data) # TypeError: unhashable type: list # ✅ 解决转换为可哈希形式 unique set(tuple(x) if isinstance(x, list) else x for x in data) # 结果: {1, 2, 5, (3, 4)}场景2缓存/记忆化pythonfrom functools import lru_cache lru_cache(maxsize128) def fibonacci(n): 缓存需要参数可哈希 if n 2: return n return fibonacci(n-1) fibonacci(n-2) # ✅ 参数 int 可哈希可以缓存 fibonacci(10) # ❌ 如果参数是列表不能使用 lru_cache场景3字典统计频率python# ✅ 使用可哈希类型作为键 freq {} words [apple, banana, apple] for word in words: freq[word] freq.get(word, 0) 1 # word 是 str可哈希 # ❌ 不能统计列表的频率 data [[1,2], [1,2], [3,4]] freq {} for item in data: freq[item] freq.get(item, 0) 1 # TypeError八、如何让自定义类可哈希pythonclass Point: def __init__(self, x, y): self.x x self.y y # 实现 __hash__ 方法 def __hash__(self): return hash((self.x, self.y)) # 实现 __eq__ 方法 def __eq__(self, other): if not isinstance(other, Point): return False return self.x other.x and self.y other.y # 使其不可变可选 def __setattr__(self, name, value): if hasattr(self, name): raise AttributeError(fCannot modify {name}) super().__setattr__(name, value) # 现在 Point 对象可以作为字典键 p1 Point(1, 2) p2 Point(1, 2) d {p1: A点} print(d[p2]) # A点因为 p1 p2九、快速总结表特性可哈希不可哈希有哈希值✅❌可比较相等✅可能可以不可变✅通常可变可作字典键✅❌可作集合元素✅❌典型代表int,str,tuplelist,dict,set记忆口诀可变不可哈希不可变可哈希。字典的键和集合的元素都必须是可哈希。

更多文章