当前位置: 首页 > news >正文

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)
listint
dictfloat
setbool
bytearraystr
自定义类实例(默认)tuple
frozenset
bytes
range

有序 vs 无序

有序类型 (Ordered)无序类型 (Unordered)
listset
tuplefrozenset
strdict(Python3.7前)
range
dict(Python3.7+)

可哈希 vs 不可哈希

可哈希类型(可作为字典键)不可哈希类型
int,float,boollist
strdict
tuple(元素都哈希)set
frozensetbytearray
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")字符串转整数

八、各类型字面量速查

类型字面量示例
int42,0xFF(十六进制),0o12(八进制),0b1010(二进制)
float3.14,1.2e-5
complex3+4j
str'单引号',"双引号",'''三单引号''',"""三双引号"""
list[1, 2, 3]
tuple(1, 2, 3)1, 2, 3
dict{'key': 'value'}
set{1, 2, 3}
boolTrue,False
NoneNone

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


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


一、什么是哈希?


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


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

# ✅ 正确:使用可哈希类型作为字典键 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:去重时的问题

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

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

# ✅ 使用可哈希类型作为键 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

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,tuplelist,dict,set

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

http://www.jsqmd.com/news/658709/

相关文章:

  • SQL处理大规模分组聚合的内存限制_调整服务器配置
  • DPABI/DPARSF新手避坑指南:从DICOM到NIFTI,我的预处理血泪史
  • 《算法竞赛中的初等数论》精讲:从零到精通的十五万字实战指南
  • OpenClaw 低代码部署教程 小白也能快速上手
  • 基于LightGBM与多因子指标的股票涨跌预测实战
  • 游戏引擎‘潜规则’:为什么你的法线贴图在Unity里凸,到UE4里就凹了?
  • 【UE5】Groom毛发系统进阶指南——从3DsMax到UE的毛发材质与物理模拟全流程
  • 2026年质量好的PETG包装管/PS包装管横向对比厂家推荐 - 品牌宣传支持者
  • SerialPlot终极指南:5个技巧掌握实时串口数据可视化
  • Go语言怎么做链路追踪_Go语言分布式链路追踪教程【精选】.txt
  • 互联网大厂 Java 求职面试:从音视频场景到微服务技术的探讨
  • PY烧录器从入门到量产:手把手教你批量烧录PY32F002B(附UID加密实战)
  • PCIe硬件电路设计实战:从理论到PCB布局的关键要点
  • LeetCode 3761. 镜像对之间最小绝对距离 (多算法优化版)
  • 塑料件用润滑脂有什么讲究
  • Terraform 从入门到精通:一篇彻底搞懂基础设施即代码(IaC)——用代码定义云,实现跨云、安全、可审计的自动化基础设施管理
  • 光刻原理--从惠更斯-菲涅尔到傅里叶光学
  • STM32F103ZET6实战:FreeRTOSv202406.01-LTS移植避坑指南
  • 保姆级教程:Windows下ComfyUI环境配置,从驱动到CUDA再到PyTorch版本一条龙搞定
  • BetterNCM-Installer:一键解锁网易云音乐PC版的终极插件管理器
  • 从零开始:30分钟搭建AI驱动的自动化测试平台Testsigma
  • 2026软著审核全面收紧!驳回率飙升背后,这份“通关指南”请收好
  • LeetCode 3379. 转换数组 详细技术解析
  • 七、区块量化交易:Binance API 实战指南
  • 用DBSCAN给异常检测“打辅助”:实战识别电商评论中的刷单水军
  • golang如何实现滑动窗口计数器_golang滑动窗口计数器实现思路
  • pcl-vtk
  • Cursor Free VIP技术方案解析:如何通过设备身份管理突破AI编程助手限制
  • FanControl深度解析:如何解决AMD显卡风扇控制失效的3种专业方案?
  • Matlab 5G NR信道建模实战:CDL信道API参数配置与性能分析