Python中可变与不可变数据类型的深度解析

青禾
青禾
发布时间:2026-10-16| 3人浏览过
原创

本文深入解析Python中可变与不可变数据类型的核心区别。通过内存地址(id)的变化规律,阐明不可变类型(如int、str、tuple)在赋值时创建新对象,而可变类型(list、dict、set)在原地修改。重点解析元组包含可变元素时的特殊行为,帮助开发者理解引用机制与内存管理。

一、可变类型与不可变类型的特点

1. 不可变数据类型

不可变数据类型在首次声明赋值时,会在内存中开辟一块空间以存储该值。变量本身并不直接存储这个值,而是存储指向该内存空间的地址。通过该地址,变量即可访问数据。所谓“不可变”,是指无法直接修改内存中已存储的数据值。因此,当修改变量的赋值时,系统实际上是在内存中重新开辟一块新空间来存放新数据,并将变量指向新的地址。此时,原变量不再引用旧数据的内存地址,而是转向引用新数据的地址。

示例说明:

>>> x = 18
>>> id(x)
4497811200
>>> id(18)
4497811200
>>> x = 19 
>>> id(x)
4497811232
>>> id(18)
4497811200
>>> y = 18
>>> id(y)
4497811200
>>>

初始状态 x = 18,系统开辟地址为 4497811200 的内存空间存放数值 18。随后执行 x = 19,系统重新开辟地址为 4497811232 的新内存空间存放数值 19。这一过程体现了“不可变”的含义:数值 18 和 19 在各自内存中的地址固定不变。若将 18 赋值给 y(即 y = 18),则 y 指向的地址同样为 4497811200,与 x 初始指向一致。

2. 可变数据类型

基于对不可变数据类型的理解,可变数据类型指变量所指向的内存地址处的内容可以被直接修改。

>>> x = [1,2,3]
>>> id(x)
4501838920
>>> y = [1,2,3]
>>> z = [1,2,3]
>>> id(y)
4501838600
>>> id(z)
4501838664

从另一个角度观察:

对于可变类型,当变量的值发生更改时,其对应的内存地址保持不变。具备这种特性的数据类型被称为可变数据类型。

对于不可变类型,当变量的值发生更改时,系统会分配新的内存地址,即原内存地址发生改变。具备这种特性的数据类型被称为不可变数据类型。

#a的值改变了,a对应的内存地址也改变了
>>> a=1
>>> id(a)
4497810656
>>> a = 2
>>> id(2)
4497810688
#直接对a操作,相当于拷贝了一份a的值,在其他内存地址操作,a的值不变
>>> a+1
3
>>> id(a)
4497810688
>>> a
2
#b的值改变了,b对应的内存地址不变,第一次给b赋值的时候,给b划分一块内存空间,该空间就不变了
>>> b = [1,2,3]
>>> id(b)
4501839496
#直接对b操作,b的值改变,b指向的内存空间不变
>>> b.append(4)
>>> id(b)
4501839496
>>> b
[1, 2, 3, 4]
>>>

二、哪些是可变类型哪些是不可变类型

不可变类型包括:Number(数字)、String(字符串)、Tuple(元组)。

#整型
a = 1
print(id(a), type(a))
a = 2
print(id(a), type(a))
# 4361254304 <class 'int'>
# 4361254336 <class 'int'>
#字符串
b = 'anne'
print(id(b),type(b))
b = 'anne1995'
print(id(b),type(b))
# 4363638744 <class 'str'>
# 4363684784 <class 'str'>
#元组
c1 = ['1','2']
c = (1,2,c1)
print(c,id(c),type(c))
c1[1] = 'djx'
print(c,id(c),type(c))
# (1, 2, ['1', '2']) 4363948248 <class 'tuple'>
# (1, 2, ['1', 'djx']) 4363948248 <class 'tuple'>

可变类型包括:Set(集合)、List(列表)、Dictionary(字典)。

#集合
s = {1, 'd', '34', '1', 1}
print(s, type(s), id(s))
s.add('djx')
print(s, type(s), id(s))
# {1, '1', 'd', '34'} <class 'set'> 4401385256
# {1, '1', '34', 'd', 'djx'} <class 'set'> 4401385256
#列表
list = [1,'q','qwer',True]
print(list,type(list),id(list))
list.append('djx')
print(list,type(list),id(list))
# [1, 'q', 'qwer', True] <class 'list'> 4401113608
# [1, 'q', 'qwer', True, 'djx'] <class 'list'> 4401113608
#字典
tuple = (1)
dic = {1:2}
d = { tuple:1,'key2':'djx','key3':'li'}
print(d,type(d),id(d))
d['key4'] = 'haha'
print(d,type(d),id(d))
# {1: 1, 'key2': 'djx', 'key3': 'li'} <class 'dict'> 4401075976
# {1: 1, 'key2': 'djx', 'key3': 'li', 'key4': 'haha'} <class 'dict'> 4401075976

注意:当元组的值发生变化但内存地址未变时,我们仍称其为不可变类型。原因在于实际发生变化的可能是元组内部包含的列表元素,而列表属于可变类型。即使列表的值改变后其内存地址不变,但元组本身的定义属性决定了它是不可变的。

元组常被称为“只读列表”,意味着其数据可以被查询,但不能被直接修改。

以上即为 Python 数据类型可变与不可变的深入分析内容,更多关于 Python 可变不可变数据类型的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。