Python中的数据类型可以分为可变和不可变两大类,同时也可以按是否为容器类型来分类。下面我将详细总结Python中主要数据类型的特性,包括可变性、容器性质、修改方式等。
一、基本数据类型分类
1. 不可变类型(Immutable)
-
创建后不能被修改
-
如果"修改",实际上是创建了新对象
-
线程安全
2. 可变类型(Mutable)
-
创建后可以被修改
-
修改是在原对象上进行
-
非线程安全
二、具体数据类型特性
1. 数字类型(不可变)
整型(int)
a = 10
b = a # b和a指向同一个对象
a = 20 # 创建了新对象,b不受影响
浮点型(float)
x = 3.14
y = x
x = 2.71 # y仍然是3.14
布尔型(bool)
flag = True
flag = False # 实际上是创建了新对象
特性:
-
不可变
-
非容器
-
值不可修改(只能重新赋值)
2. 字符串(不可变)
s = "hello"
s[0] = 'H' # 报错:'str' object does not support item assignment
s = s + " world" # 创建了新字符串
特性:
-
不可变
-
是容器(可迭代,包含字符序列)
-
内容不可修改
-
支持切片操作(返回新字符串)
3. 列表(可变)
lst = [1, 2, 3]
lst[0] = 100 # 直接修改原列表
lst.append(4) # 原地添加元素
特性:
-
可变
-
是容器
-
内容可修改
-
支持增删改查操作
-
可包含不同类型元素
4. 元组(不可变)
t = (1, 2, 3)
t[0] = 100 # 报错:'tuple' object does not support item assignment
特性:
-
不可变
-
是容器
-
内容不可修改
-
比列表更节省内存
-
可用作字典的键
5. 字典(可变)
d = {'name': 'Alice', 'age': 25}
d['age'] = 26 # 修改值
d['city'] = 'Beijing' # 添加新键值对
特性:
-
可变
-
是容器
-
键必须是不可变类型(字符串、数字、元组等)
-
值可以是任意类型
-
Python 3.7+ 保持插入顺序
6. 集合(可变)
s = {1, 2, 3}
s.add(4) # 添加元素
s.remove(2) # 删除元素
特性:
-
可变
-
是容器
-
元素必须是不可变类型
-
无序且不重复
-
支持集合运算(并集、交集等)
不可变集合(frozenset)
fs = frozenset([1, 2, 3])
fs.add(4) # 报错:'frozenset' object has no attribute 'add'
特性:
-
不可变版本的集合
-
可用作字典的键或其他集合的元素
三、数据类型对比表
数据类型 | 可变性 | 是否容器 | 元素要求 | 是否有序 | 是否可哈希 |
---|---|---|---|---|---|
int | 不可变 | 否 | - | - | 是 |
float | 不可变 | 否 | - | - | 是 |
bool | 不可变 | 否 | - | - | 是 |
str | 不可变 | 是 | 字符 | 是 | 是 |
list | 可变 | 是 | 任意 | 是 | 否 |
tuple | 不可变 | 是 | 任意 | 是 | 是 |
dict | 可变 | 是 | 键不可变 | 3.7+是 | 否 |
set | 可变 | 是 | 不可变 | 否 | 否 |
frozenset | 不可变 | 是 | 不可变 | 否 | 是 |
四、重要概念解释
1. 可哈希性(Hashable)
-
可哈希对象才能作为字典的键或集合的元素
-
不可变类型通常可哈希(list、dict、set除外)
-
可变类型不可哈希
2. 深浅拷贝问题
-
不可变类型:赋值、浅拷贝、深拷贝效果相同
-
可变类型:
-
赋值:只是创建新引用
-
浅拷贝:只拷贝最外层容器
-
深拷贝:递归拷贝所有层级
-
import copy
# 列表(可变类型)示例
lst1 = [1, [2, 3]]
lst2 = lst1 # 赋值
lst3 = lst1.copy() # 浅拷贝
lst4 = copy.deepcopy(lst1) # 深拷贝
3. 函数参数传递
-
不可变类型作为参数:函数内修改不会影响原值
-
可变类型作为参数:函数内修改会影响原值
def modify(num, lst):
num += 1
lst.append(100)
a = 10
b = [1, 2]
modify(a, b)
print(a) # 输出10(不变)
print(b) # 输出[1, 2, 100](已修改)
五、使用建议
-
不可变类型适用于:
-
需要哈希的场景(字典键、集合元素)
-
多线程环境
-
需要确保不被意外修改的情况
-
-
可变类型适用于:
-
需要频繁修改数据的场景
-
构建复杂数据结构
-
需要原地操作的场景
-
-
性能考虑:
-
元组比列表创建和访问更快
-
集合比列表的成员检测更快
-
字符串拼接推荐使用join()而非+
-