基于本文回答
0
评论

Python 中列表(List)和元组(Tuple)的区别?

知识点图片

Python 中的 列表(List)元组(Tuple) 都是用于存储有序数据集合的序列,但它们之间有几个关键的区别。

最核心的区别在于:列表是可变的(Mutable),而元组是不可变的(Immutable)。

以下是详细的对比分析:

1. 可变性 (Mutability)

  • 列表 (List):可变的。这意味着创建列表后,你可以随意修改、添加或删除其中的元素。
  • 元组 (Tuple):不可变的。一旦创建,就不能修改其内容(不能增加、删除或更改元素)。
python
# 列表
my_list = [1, 2, 3]
my_list[0] = 100  # 合法,列表变为 [100, 2, 3]

# 元组
my_tuple = (1, 2, 3)
# my_tuple[0] = 100  # 报错!TypeError: 'tuple' object does not support item assignment

2. 语法 (Syntax)

  • 列表: 使用方括号 [] 定义。
  • 元组: 使用圆括号 () 定义。
    • 注意: 定义只有一个元素的元组时,必须加逗号,例如 (1,),否则 Python 会将其视为普通的括号运算。
python
lst = [1, 2, 3]
tup = (1, 2, 3)
single_tup = (1,) 
not_a_tup = (1)   # 这是整数 1

3. 性能与内存 (Performance & Memory)

  • 元组: 由于是不可变的,Python 可以在内部对其进行优化。元组通常比列表占用更少的内存,且创建和遍历的速度稍微快一些
  • 列表: 为了支持动态扩容(添加元素),列表需要分配额外的内存空间(Overhead),因此占用内存较大。
python
import sys
a_list = [1, 2, 3, 4, 5]
a_tuple = (1, 2, 3, 4, 5)

print(sys.getsizeof(a_list))   # 结果通常较大 (例如 104 bytes)
print(sys.getsizeof(a_tuple))  # 结果通常较小 (例如 80 bytes)

4. 方法支持 (Methods)

  • 列表: 拥有丰富的方法,如 append(), extend(), insert(), remove(), pop(), sort(), reverse() 等。
  • 元组: 支持的方法很少,主要是 count() (统计元素出现次数) 和 index() (查找元素索引)。

5. 作为字典的键 (Dictionary Keys)

  • 元组: 因为是不可变的(且如果其内部元素也是不可变的),它是可哈希的(Hashable),所以可以作为字典的 Key,也可以放入集合(Set)中。
  • 列表: 因为是可变的,它是不可哈希的(Unhashable),所以不能作为字典的 Key。
python
my_dict = {}
my_tuple = (1, 2)
my_list = [1, 2]

my_dict[my_tuple] = "合法"
# my_dict[my_list] = "报错"  # TypeError: unhashable type: 'list'

6. 使用场景 (Use Cases)

虽然两者都能存数据,但在 Python 惯例中:

  • 列表: 通常用于存储同构数据(即相同类型的数据),且数据长度可能会发生变化。类似于数据库中的“一列”数据。
  • 元组: 通常用于存储异构数据(不同类型的数据),表示一个特定的结构或记录。类似于数据库中的“一行”记录(例如:(姓名, 年龄, 性别))。

总结对比表

特性 列表 (List) 元组 (Tuple)
可变性 可变 (Mutable) 不可变 (Immutable)
语法 [1, 2, 3] (1, 2, 3)
速度/性能 稍慢 稍快
内存占用 较大 较小
方法数量 多 (append, remove...) 少 (count, index)
作字典Key 不可以 可以
语义 变长序列,同类数据 定长记录,结构化数据

一个特殊的陷阱

虽然元组本身是不可变的,但如果元组中包含了一个可变对象(如列表),那么这个内部的列表是可以被修改的。

python
t = (1, 2, [3, 4])
# t[0] = 5      # 报错:不能修改元组的引用
t[2][0] = 99    # 合法!因为 t[2] 指向的是一个列表,列表内部是可变的
print(t)        # 输出: (1, 2, [99, 4])
右滑查看面试常问