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 选择建议

  1. 需要有序、可变的元素集合 → 使用列表
  2. 需要不可变的数据集合 → 使用元组
  3. 需要键值对映射 → 使用字典
  4. 需要去重或集合运算 → 使用集合
  5. 需要快速成员检查 → 使用集合

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 代码。建议在实际项目中多加练习,深入理解每种容器的适用场景和性能特点。

更多推荐