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

本文系统总结了Python中的数据类型分类及特性。


主要内容包括:

  1. 数据类型分类:基本类型(int/float/str等)、序列类型(list/tuple/range)、映射类型(dict)、集合类型(set/frozenset)和二进制序列类型(bytes/bytearray);
  2. 类型特性对比:可变性(list/dict可变,tuple/str不可变)、有序性(list有序,set无序)和可哈希性(可哈希类型可作为字典键);
  3. 可哈希性详解:定义了可哈希对象的条件(不可变、有哈希值、可比较相等),列举了常见可哈希与不可哈希类型,并说明了可哈希性的实际应用场景;
  4. 类型转换与判断方法。

全文通过对比表格和示例代码,清晰展示了Python数据类型的核心特性与使用要点。


Python 中主要数据类型分类总结


一、基本数据类型

类型 名称 示例 特点 可变性
int 整数 42, -10, 0b1010 任意精度,无范围限制 不可变
float 浮点数 3.14, -0.5, 1.2e-5 双精度浮点数 不可变
complex 复数 3+4j, 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 字节串 b'hello', bytes([65,66]) 0-255的整数序列 不可变
bytearray 字节数组 bytearray(b'hello') 可修改的字节序列 可变
memoryview 内存视图 memoryview(b'hello') 直接访问内存数据 可变

六、各类型对比速查

可变 vs 不可变

可变类型 (Mutable) 不可变类型 (Immutable)
list int
dict float
set bool
bytearray str
自定义类实例(默认) tuple
frozenset
bytes
range

有序 vs 无序

有序类型 (Ordered) 无序类型 (Unordered)
list set
tuple frozenset
str dict (Python3.7前)
range
dict (Python3.7+)

可哈希 vs 不可哈希

可哈希类型(可作为字典键) 不可哈希类型
int, float, bool list
str dict
tuple(元素都哈希) set
frozenset bytearray
None

七、类型判断与转换

操作 示例 说明
类型判断 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") 字符串转整数

八、各类型字面量速查

类型 字面量示例
int 42, 0xFF(十六进制), 0o12(八进制), 0b1010(二进制)
float 3.14, 1.2e-5
complex 3+4j
str '单引号', "双引号", '''三单引号''', """三双引号"""
list [1, 2, 3]
tuple (1, 2, 3)1, 2, 3
dict {'key': 'value'}
set {1, 2, 3}
bool True, False
None None

提示 :Python 是动态强类型语言,变量无需声明类型,但不同类型之间通常不会自动转换。


可哈希 (Hashable) 与 不可哈希 (Unhashable) 详解


一、什么是哈希?


哈希 是将任意大小的数据(如字符串、数字)通过哈希函数 转换成固定长度的唯一标识(哈希值)的过程。


python

python 复制代码
# 哈希值示例
hash(42)      # 输出: 42
hash("hello") # 输出: -2091548855179221912
hash((1,2,3)) # 输出: 529344067295497451

二、可哈希类型的特征

一个对象是可哈希的,需要满足以下条件:

  1. 有哈希值 - 实现 __hash__() 方法

  2. 可比较相等 - 实现 __eq__() 方法

  3. 不可变 - 创建后内容不能改变


三、常见可哈希与不可哈希类型

类型 可哈希? 原因
int ✅ 是 不可变
float ✅ 是 不可变
bool ✅ 是 不可变
str ✅ 是 不可变
tuple ✅ 是 不可变(前提:内部元素也都可哈希)
frozenset ✅ 是 不可变
None ✅ 是 单例对象
list ❌ 否 可变,内容可改变
dict ❌ 否 可变
set ❌ 否 可变
bytearray ❌ 否 可变

四、为什么需要可哈希?

可哈希对象可以:

  • 作为字典的键 (dict key)

  • 作为集合的元素 (set element)

python

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

python 复制代码
# ✅ 元组内都是可哈希元素 → 元组可哈希
t1 = (1, 2, "a")
hash(t1)  # 成功

# ❌ 元组内包含不可哈希元素 → 元组不可哈希
t2 = (1, [2, 3], "a")
hash(t2)  # TypeError: unhashable type: 'list'

六、如何判断对象是否可哈希?

python

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:去重时的问题

python

python 复制代码
data = [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:缓存/记忆化

python

python 复制代码
from functools import lru_cache

@lru_cache(maxsize=128)
def fibonacci(n):
    """缓存需要参数可哈希"""
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

# ✅ 参数 int 可哈希,可以缓存
fibonacci(10)

# ❌ 如果参数是列表,不能使用 lru_cache

场景3:字典统计频率

python

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

八、如何让自定义类可哈希?

python

python 复制代码
class 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(f"Cannot 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, tuple list, dict, set

记忆口诀 :可变不可哈希,不可变可哈希。字典的键和集合的元素,都必须是可哈希。

相关推荐
m0_74035242几秒前
mysql安装完成后如何配置慢查询阈值_mysql日志监控方法
jvm·数据库·python
m0_74079636几秒前
如何查找SQL中最常见的元素_结合GROUP BY与COUNT
jvm·数据库·python
wang3zc几秒前
HTML怎么标注成就连续打卡中断_HTML“断连,重新开始”提示【方法】
jvm·数据库·python
_37627153几秒前
如何正确验证 GOPATH 和 PATH 环境变量是否生效
jvm·数据库·python
m0_736439303 分钟前
如何在phpMyAdmin中处理权限更改不生效_FLUSH PRIVILEGES命令执行
jvm·数据库·python
2401_824697664 分钟前
优化文本分类中堆叠模型的网格搜索性能:避免训练卡顿的实用指南
jvm·数据库·python
Mzyh6 分钟前
通过蓝印RPA获取到飞书聊天中的信息图片-自动化
windows·python·ai·自动化·飞书·rpa
2403_883261097 分钟前
CSS如何避免浮动元素换行_计算所有浮动元素的总宽度不超过父容器宽度
jvm·数据库·python
复园电子8 分钟前
RPA自动化最后一公里:通过Python调用RESTful API挂载物理U盾实战
python·自动化·rpa
2601_956139428 分钟前
新零售品牌全案公司找哪家
人工智能·python·零售