Python 中的元组(Tuple)vs 列表(List)vs 集合(Set)

更新于 2026-01-13

Jerry Ng 2021-08-10

在 Python 中,有四种内置的数据类型可用于存储数据集合。这些内置数据类型分别是:列表(list)、元组(tuple)、集合(set)和字典(dict),它们各自具有不同的特性和用途。

在本文中,我们将深入探讨 Python 中的列表、元组和集合。我们会详细比较它们之间的区别,并讨论在什么场景下应使用哪种数据类型。

由于字典(Dictionary)通过键(key)关联其对应的值(value),其使用场景与仅包含值的列表、元组和集合有着本质的不同,因此本次讨论将不包括字典。

为简化说明,我将集合(Set)和字典(Dictionary)互换使用,因为它们底层都基于哈希表(Hash Table,也称哈希映射 Hash Map)。

为什么我们需要关心这个问题?

在大多数情况下,这些数据类型在应用程序中可以互换使用而不会造成太大问题。

然而,试想一下:如果我们被要求在一个庞大的“干草堆”(haystack)中查找一根“针”(needle),那么从速度和内存效率的角度来看,最高效的方式是什么?

这个“干草堆”应该用列表(List)吗?还是元组(Tuple)?或者为什么不总是使用集合(Set)(或字典 Dictionary)呢?使用它们时又有哪些需要注意的陷阱?

让我们深入探讨!

列表、元组和集合之间的区别

重复元素(Duplicates)

如果我要打个比方,列表和元组就像是 Python 中的亲兄弟,而集合(或字典)则是它们的表亲。

与列表或元组不同,集合不能包含重复元素。换句话说,集合中的元素是唯一的。

set_example = {1, 1, 2, 3, 3, 3}
# 结果: {1, 2, 3}

fruit_set = {'🍎', '🍓', '🍐', '🍎', '🍎', '🍓'}
# 结果: {'🍎', '🍐', '🍓'}

有了这一认识,我们现在就知道:集合也可以用来从列表中去除重复项!

排序顺序(Sorting Order)

你可能听说过这样一句话:“在 Python 中,集合和字典是无序的。”但这句话如今只说对了一半,具体取决于你使用的 Python 版本。

在 Python 3.6 之前,字典和集合不保留插入顺序。例如,如果你在 Python 3.5 中运行以下代码:

# Python 3.5 中的示例

fruit_size = {} 
fruit_size['🍎'] = 12 
fruit_size['🍐'] = 16 
fruit_size['🍇'] = 20 
fruit_size
# 输出可能是: {'🍎': 12, '🍇': 20, '🍐': 16}

💡
小贴士:你可以使用 asdfpyenv 的替代工具)轻松在不同 Python 版本之间切换。

如今,这一说法已经过时好几年了。从 Python 3.7 开始,字典和集合官方保证按照插入顺序进行排序

顺便提一句,列表和元组始终是有序的对象序列

可变性(Mutability)

当我们说一个对象是“可变的”(mutable),其实就是一种花哨的说法,意思是该对象的内部状态可以被修改。

这里的关键区别在于:元组是不可变的(immutable,即不可更改),而列表和集合是可变的

尽管集合是可变的,但我们无法通过索引或切片来访问或修改集合中的任意元素。因此,我们只能向集合中添加新元素,而不能修改已有元素。

请注意,集合中的 update() 方法仅仅表示可以一次性添加多个元素。

索引(Indexing)

列表和元组都支持索引和切片操作,而集合则不支持。

fruit_list = ['🍎', '🍓', '🍐']
fruit_list[1]
# '🍓'

animal_tuple = ('🐶', '🐱', '🐮')
animal_tuple[2]
# '🐮'

vehicle_set = {'🚐', '🏍', '🚗'}
vehicle_set[0]
# TypeError: 'set' object is not subscriptable(集合对象不支持下标访问)

何时使用列表 vs 元组?

正如前面提到的,元组是不可变的,而列表是可变的。同样地,元组本质上是固定大小的,而列表是动态的。

a_tuple = tuple(range(1000))
a_list = list(range(1000))
a_tuple.__sizeof__()  # 8024 字节
a_list.__sizeof__()   # 9088 字节

使用列表的情况:

  • 当你需要对集合进行修改时。
  • 当你需要从集合中删除元素或添加新元素时。

使用元组的情况:

  • 如果你的数据不应该(或不需要)被更改。
  • 元组比列表更快。如果你定义的是一组常量值,并且唯一要做的就是遍历它,那么应优先使用元组。
  • 如果你需要将一组元素用作字典的键(key),可以使用元组。因为列表是可变的(属于不可哈希类型),永远不能作为字典的键。

何时使用集合 vs 列表/元组?

由于集合底层使用哈希表作为其数据结构,因此在检查某个元素是否存在于集合中时(例如 x in a_set),集合的速度非常快。

其原理在于:在哈希表中查找一个项目的时间复杂度是 O(1)(常数时间)。

“那我是不是应该总是使用集合或字典?”

本质上,如果你不需要存储重复元素,那么集合一定比列表更好。就这么简单。

总结

如果你和我一样是个数据性能爱好者,可以看看下面这张关于元组、列表和集合在迭代或检查元素是否存在时的速度对比图。

主要结论如下:

  • 如果你需要存储重复元素,请选择列表或元组。
  • 在列表和元组之间做选择时,请考虑可变性:如果你需要不可变性,就选择元组。
  • 如果你不需要存储重复元素,始终优先选择集合或字典。哈希映射在判断某个对象是否存在于集合(或字典)中时,速度显著更快(例如 x in set_or_dict)。