Python 容器数据类型详解:列表、元组、字典与集合
·
1. 引言
Python 作为一门功能强大的编程语言,提供了多种内置的容器数据类型,用于高效地存储和组织数据。这些容器类型是 Python 编程的基础,掌握它们对于编写高效、可读性强的代码至关重要。本文将深入探讨 Python 中最常用的四种容器数据类型:列表(List)、元组(Tuple)、字典(Dictionary)和集合(Set),帮助您全面理解它们的特点、用法和适用场景。
2. 列表(List)
2.1 基本概念
列表是 Python 中最常用的可变序列类型,用于存储有序的元素集合。列表中的元素可以是不同类型的数据,并且可以动态地添加、删除或修改。
2.2 创建与基本操作
# 创建列表
empty_list = []
numbers = [1, 2, 3, 4, 5]
mixed_list = [1, "hello", 3.14, True]
# 访问元素
print(numbers[0]) # 输出: 1
print(numbers[-1]) # 输出: 5(最后一个元素)
# 修改元素
numbers[0] = 10
print(numbers) # 输出: [10, 2, 3, 4, 5]
# 切片操作
print(numbers[1:3]) # 输出: [2, 3]
print(numbers[:3]) # 输出: [10, 2, 3]
print(numbers[2:]) # 输出: [3, 4, 5]
2.3 常用方法
# 添加元素
fruits = ["apple", "banana"]
fruits.append("orange") # 末尾添加
fruits.insert(1, "grape") # 指定位置插入
fruits.extend(["kiwi", "mango"]) # 扩展列表
# 删除元素
fruits.remove("banana") # 删除指定元素
popped = fruits.pop() # 删除并返回最后一个元素
del fruits[0] # 删除指定索引元素
# 其他操作
print(len(fruits)) # 列表长度
print("apple" in fruits) # 成员检查
fruits.sort() # 排序
fruits.reverse() # 反转
2.4 列表推导式
列表推导式提供了一种简洁创建列表的方法:
# 创建平方数列表
squares = [x**2 for x in range(10)]
print(squares) # 输出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# 带条件的列表推导式
even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(even_squares) # 输出: [0, 4, 16, 36, 64]
3. 元组(Tuple)
3.1 基本概念
元组是不可变的序列类型,一旦创建就不能修改。元组通常用于存储不可变的数据集合,如坐标、配置参数等。
1、元组创建后无法修改、新增、删除内部元素,列表[]则支持增删改;
2、底层原理:元组内存空间固定分配,哈希值稳定;列表长度可变、内存动态扩容,哈希值不稳定;
3、变通方案:想修改只能转列表操作后再转回元组
3.2 创建与基本操作
# 创建元组
empty_tuple = ()
single_tuple = (1,) # 注意逗号,否则不是元组
coordinates = (10, 20)
person = ("Alice", 25, "Engineer")
# 访问元素
print(coordinates[0]) # 输出: 10
print(person[1:]) # 输出: (25, 'Engineer')
# 元组解包
x, y = coordinates
print(f"x={x}, y={y}") # 输出: x=10, y=20
# 交换变量值
a, b = 1, 2
a, b = b, a # 交换
print(a, b) # 输出: 2 1
3.3 不可变性与优势
# 元组不可修改
my_tuple = (1, 2, 3)
# my_tuple[0] = 10 # 会报错: TypeError
# 正确的写法,转列表操作后再转回元组
my_tuple = (1,2,3)
temp = list(my_tuple)
temp[0] = 10
my_tuple = tuple(temp)
print(my_tuple) # (10, 2, 3)
# 元组作为字典键
locations = {
(40.7128, -74.0060): "New York",
(51.5074, -0.1278): "London"
}
print(locations[(40.7128, -74.0060)]) # 输出: New York
4. 字典(Dictionary)
4.1 基本概念
字典是 Python 中的映射类型,用于存储键值对。字典中的键必须是不可变类型(如字符串、数字、元组),而值可以是任意类型。
| 写法 | 适用场景 | 限制 |
|---|---|---|
| {} | 空字典、批量多键值、key 含特殊字符 / 数字开头 | 手动敲冒号分隔 |
| dict(a=1,b=2) | key 是简单英文单词、无特殊符号 | key 必须符合 Python 变量命名规则 |
| dict([(“k1”,v1),(“k2”,v2)]) | 已有列表 / 元组序列转字典 | 序列必须是成对 (key,value) |
4.2 创建与基本操作
# 创建字典
empty_dict = {}
person = {"name": "Alice", "age": 25, "city": "New York"}
grades = dict(math=90, english=85, science=92)
# 访问元素
print(person["name"]) # 输出: Alice
print(person.get("age")) # 输出: 25
print(person.get("salary", 0)) # 输出: 0(默认值)
# 添加/修改元素
person["email"] = "alice@example.com"
person["age"] = 26
# 删除元素
del person["city"]
removed = person.pop("age")
4.3 常用方法
遍历字典
# 第一种:只循环 key(默认遍历字典的键)
for key in person:
print(f"{key}: {person[key]}")
# 第二种:.items() 同时遍历 key + value(更推荐)
for key, value in person.items():
print(f"{key}: {value}")
# 只遍历所有值 .values()
for val in person.values():
print(val)
# 输出:Alice、25、New York
# 只遍历所有键 .keys()(和直接for key in person效果一模一样)
for k in person.keys():
print(k)
# 输出:name、age、city
# 获取所有键和值
keys = list(person.keys())
values = list(person.values())
# 字典推导式
squares = {x: x**2 for x in range(5)}
print(squares) # 输出: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
4.4 嵌套字典
# 嵌套字典示例
students = {
"Alice": {
"age": 20,
"grades": {"math": 90, "english": 85},
"courses": ["CS101", "MATH201"]
},
"Bob": {
"age": 21,
"grades": {"math": 88, "english": 92},
"courses": ["PHYS101", "CHEM201"]
}
}
# 访问嵌套数据
print(students["Alice"]["grades"]["math"]) # 输出: 90
5. 集合(Set)
5.1 基本概念
集合是无序的、不重复的元素集合。集合支持数学上的集合运算,如并集、交集、差集等。
5.2 创建与基本操作
# 创建集合
empty_set = set() # 注意:{} 创建的是空字典
numbers = {1, 2, 3, 4, 5}
colors = set(["red", "green", "blue"])
# 添加和删除元素
numbers.add(6)
numbers.remove(3) # 如果元素不存在会报错
numbers.discard(10) # 如果元素不存在不会报错
popped = numbers.pop() # 随机删除并返回一个元素
# 集合运算
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}
print(set1 | set2) # 并集: {1, 2, 3, 4, 5, 6}
print(set1 & set2) # 交集: {3, 4}
print(set1 - set2) # 差集: {1, 2}
print(set1 ^ set2) # 对称差集: {1, 2, 5, 6}
5.3 集合推导式
# 集合推导式
even_squares = {x**2 for x in range(10) if x % 2 == 0}
print(even_squares) # 输出: {0, 4, 16, 36, 64}
# 去重应用
numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
unique_numbers = set(numbers)
print(unique_numbers) # 输出: {1, 2, 3, 4}
6. 容器类型比较与选择
6.1 特性对比
| 特性 | 列表 | 元组 | 字典 | 集合 |
|---|---|---|---|---|
| 可变性 | 可变 | 不可变 | 可变 | 可变 |
| 有序性 | 有序 | 有序 | 无序(Python 3.7+ 有序) | 无序 |
| 元素重复 | 允许 | 允许 | 键不允许重复 | 不允许 |
| 索引方式 | 整数索引 | 整数索引 | 键索引 | 不支持索引 |
| 主要用途 | 存储有序集合 | 存储不可变数据 | 键值对映射 | 去重、集合运算 |
6.2 性能考虑
import time
# 成员检查性能比较
large_list = list(range(1000000))
large_set = set(large_list)
# 列表查找(O(n))
start = time.time()
999999 in large_list
list_time = time.time() - start
# 集合查找(O(1))
start = time.time()
999999 in large_set
set_time = time.time() - start
print(f"列表查找时间: {list_time:.6f}秒")
print(f"集合查找时间: {set_time:.6f}秒")
6.3 选择建议
- 需要有序、可变的元素集合 → 使用列表
- 需要不可变的数据集合 → 使用元组
- 需要键值对映射 → 使用字典
- 需要去重或集合运算 → 使用集合
- 需要快速成员检查 → 使用集合
7. 高级用法与技巧
7.1 容器嵌套
# 列表嵌套
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
# 字典列表
students = [
{"name": "Alice", "score": 90},
{"name": "Bob", "score": 85},
{"name": "Charlie", "score": 92}
]
# 集合的集合(需要转换为frozenset)
set_of_sets = {frozenset({1, 2}), frozenset({3, 4})}
7.2 collections 模块
from collections import defaultdict, Counter, deque
# defaultdict:带默认值的字典
word_count = defaultdict(int)
for word in ["apple", "banana", "apple", "orange"]:
word_count[word] += 1
# Counter:计数器
counter = Counter(["apple", "banana", "apple", "orange"])
print(counter.most_common(2)) # 输出: [('apple', 2), ('banana', 1)]
# deque:双端队列
queue = deque([1, 2, 3])
queue.append(4) # 右端添加
queue.appendleft(0) # 左端添加
queue.pop() # 右端弹出
queue.popleft() # 左端弹出
7.3 内存优化
# 使用生成器表达式处理大数据
large_data = (x**2 for x in range(1000000)) # 生成器,不立即创建列表
# 使用数组存储数值类型
import array
numbers = array.array('i', [1, 2, 3, 4, 5]) # 比列表更节省内存
8. 总结
Python 的容器数据类型为数据处理提供了丰富的选择。列表适合有序可变集合,元组适合不可变数据,字典适合键值映射,集合适合去重和集合运算。在实际编程中,应根据具体需求选择合适的容器类型,并合理利用它们的高级特性来提高代码的效率和可读性。
掌握这些容器类型的使用技巧,能够帮助您编写更加优雅、高效的 Python 代码。建议在实际项目中多加练习,深入理解每种容器的适用场景和性能特点。
更多推荐

所有评论(0)