Skip to content

复合数据类型(容器类型)

所属模块:语法基础
难度等级:⭐️⭐️

📌 学习目标

  • 掌握Python四种主要复合数据类型:列表、元组、字典和集合
  • 理解每种容器类型的特点、适用场景和操作方法
  • 能够根据需求选择合适的容器类型
  • 学会使用容器类型的常用方法和操作
  • 避免容器类型使用中的常见错误

📘 核心内容

1. 列表(list)

列表是有序、可变的元素集合,允许存储不同类型的元素,用方括号[]表示。

python
# 列表定义
empty_list = []  # 空列表
numbers = [1, 2, 3, 4, 5]  # 整数列表
mixed = [1, "apple", 3.14, True]  # 混合类型列表
nested = [1, [2, 3], [4, [5, 6]]]  # 嵌套列表

# 列表类型检查
print(type(numbers))  # 输出: <class 'list'>

# 访问列表元素(通过索引)
fruits = ["apple", "banana", "cherry"]
print(fruits[0])   # 第一个元素: "apple"
print(fruits[-1])  # 最后一个元素: "cherry"
print(nested[1][0])  # 嵌套列表访问: 2

# 修改列表元素
fruits[1] = "orange"
print(fruits)  # 输出: ["apple", "orange", "cherry"]

# 列表常用操作
fruits.append("date")  # 添加元素到末尾
print(fruits)  # 输出: ["apple", "orange", "cherry", "date"]

fruits.insert(1, "banana")  # 在指定位置插入元素
print(fruits)  # 输出: ["apple", "banana", "orange", "cherry", "date"]

removed = fruits.pop(2)  # 删除并返回指定位置元素
print(removed)  # 输出: "orange"
print(fruits)   # 输出: ["apple", "banana", "cherry", "date"]

fruits.remove("banana")  # 删除第一个匹配的元素
print(fruits)  # 输出: ["apple", "cherry", "date"]

# 列表切片
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(numbers[2:5])   # 索引2到4: [2, 3, 4]
print(numbers[:3])    # 开始到索引2: [0, 1, 2]
print(numbers[7:])    # 索引7到结束: [7, 8, 9]
print(numbers[::2])   # 步长为2: [0, 2, 4, 6, 8]
print(numbers[::-1])  # 反转列表: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

💡 提示:列表是Python中最常用的容器类型,适合存储有序且需要修改的元素集合。列表的索引从0开始,使用负数索引可以从末尾开始访问元素。

2. 元组(tuple)

元组是有序、不可变的元素集合,与列表类似但元素不能修改,用圆括号()表示。

python
# 元组定义
empty_tuple = ()  # 空元组
single_element = (5,)  # 单个元素的元组(注意逗号)
numbers = (1, 2, 3, 4, 5)  # 多个元素的元组
mixed = (1, "apple", 3.14, True)  # 混合类型元组
nested = (1, (2, 3), (4, (5, 6)))  # 嵌套元组

# 元组也可以省略括号(不推荐)
another_tuple = 10, 20, 30

# 元组类型检查
print(type(numbers))  # 输出: <class 'tuple'>

# 访问元组元素(与列表相同)
colors = ("red", "green", "blue")
print(colors[0])   # 第一个元素: "red"
print(colors[-1])  # 最后一个元素: "blue"

# 元组切片(与列表相同)
print(colors[1:3])  # 输出: ("green", "blue")

# 元组不可修改(会报错)
try:
    colors[0] = "yellow"
except TypeError as e:
    print(e)  # 输出: 'tuple' object does not support item assignment

# 元组常用操作
print(len(colors))  # 长度: 3
print("green" in colors)  # 检查包含: True

# 元组解包
a, b, c = (10, 20, 30)
print(a)  # 10
print(b)  # 20
print(c)  # 30

# 交换变量值(利用元组解包)
x, y = 5, 10
x, y = y, x
print(x, y)  # 输出: 10 5

💡 提示:元组的不可变性提供了数据安全性,适合存储不希望被修改的数据。元组比列表更节省内存,且可以作为字典的键,而列表不能。定义单个元素的元组时,必须在元素后加逗号,否则会被视为普通括号。

3. 字典(dict)

字典是无序(Python 3.7+保证插入顺序)的键值对集合,用于存储关联数据,用花括号{}表示,键和值之间用冒号:分隔。

python
# 字典定义
empty_dict = {}  # 空字典
person = {
    "name": "Alice",
    "age": 30,
    "is_student": False,
    "hobbies": ["reading", "hiking"]
}  # 包含多种类型值的字典

# 使用dict()构造函数创建
another_person = dict(name="Bob", age=25, is_student=True)

# 字典类型检查
print(type(person))  # 输出: <class 'dict'>

# 访问字典值(通过键)
print(person["name"])  # 输出: "Alice"
print(person.get("age"))  # 输出: 30

# 使用get()方法安全访问(键不存在时返回默认值)
print(person.get("address", "Unknown"))  # 输出: "Unknown"

# 修改字典值
person["age"] = 31
print(person["age"])  # 输出: 31

# 添加新键值对
person["address"] = "123 Main St"
print(person["address"])  # 输出: "123 Main St"

# 删除键值对
del person["is_student"]
print(person.get("is_student", "Not found"))  # 输出: "Not found"

# 字典常用操作
print(len(person))  # 键值对数量: 4
print("name" in person)  # 检查键是否存在: True

print(person.keys())    # 所有键: dict_keys(['name', 'age', 'hobbies', 'address'])
print(person.values())  # 所有值: dict_values(['Alice', 31, ['reading', 'hiking'], '123 Main St'])
print(person.items())   # 所有键值对: dict_items([('name', 'Alice'), ('age', 31), ('hobbies', ['reading', 'hiking']), ('address', '123 Main St')])

# 遍历字典
for key, value in person.items():
    print(f"{key}: {value}")

💡 提示:字典的键必须是不可变类型(如整数、字符串、元组),而值可以是任何类型。使用get()方法访问字典比直接使用[]更安全,因为当键不存在时不会抛出错误。

4. 集合(set)

集合是无序、不重复的元素集合,用于存储唯一元素和进行集合运算,用花括号{}表示。

python
# 集合定义
empty_set = set()  # 空集合(不能用{},那会创建空字典)
numbers = {1, 2, 3, 4, 5}  # 数字集合
strings = {"apple", "banana", "cherry"}  # 字符串集合

# 从列表创建集合(自动去重)
duplicates = [1, 2, 2, 3, 3, 3]
unique_numbers = set(duplicates)
print(unique_numbers)  # 输出: {1, 2, 3}

# 集合类型检查
print(type(numbers))  # 输出: <class 'set'>

# 集合常用操作
numbers.add(6)  # 添加元素
print(numbers)  # 输出: {1, 2, 3, 4, 5, 6}

numbers.remove(3)  # 删除元素(元素不存在会报错)
print(numbers)  # 输出: {1, 2, 4, 5, 6}

numbers.discard(7)  # 删除元素(元素不存在不会报错)

# 集合运算
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

print(a.union(b))     # 并集: {1, 2, 3, 4, 5, 6}
print(a.intersection(b))  # 交集: {3, 4}
print(a.difference(b))    # 差集: {1, 2}
print(a.symmetric_difference(b))  # 对称差集: {1, 2, 5, 6}

print(a.issubset(b))  # 是否为子集: False
print({3, 4}.issubset(a))  # 输出: True

# 集合遍历
for fruit in strings:
    print(fruit)

💡 提示:集合的主要用途是去重和集合运算。由于集合是无序的,不能通过索引访问元素。集合中的元素必须是不可变类型,因此不能包含列表、字典或其他集合。

5. 容器类型的选择

选择合适的容器类型取决于具体需求:

python
# 选择指南示例

# 1. 需要有序且可修改的元素集合 → 列表
shopping_list = ["牛奶", "鸡蛋", "面包"]
shopping_list.append("水果")  # 可以修改

# 2. 需要有序且不可修改的元素集合 → 元组
point = (10, 20)  # 坐标点,不应该被修改
rgb_color = (255, 0, 0)  # RGB颜色值

# 3. 需要存储键值对数据 → 字典
user = {
    "id": 1001,
    "username": "john_doe",
    "email": "john@example.com"
}

# 4. 需要存储唯一元素或进行集合运算 → 集合
tags = {"python", "programming", "tutorial"}
another_tags = {"python", "beginner", "coding"}
common_tags = tags.intersection(another_tags)  # 找出共同标签

各种容器类型的主要特点对比:

类型有序性可变性元素唯一性访问方式适用场景
列表索引存储有序且可能修改的元素
元组索引存储不可修改的有序数据
字典是(3.7+)键唯一存储键值对关联数据
集合无索引去重、集合运算

💡 提示:选择容器类型时,应优先考虑数据的使用方式而非数据本身。例如,即使都是数字,如果需要通过名称访问,应使用字典而非列表。

🔍 常见问题(FAQ)

Q:列表和元组有什么主要区别?
A:主要区别在于可变性:列表是可变的(可以添加、删除、修改元素),而元组是不可变的(创建后不能修改)。此外,元组比列表更节省内存,且可以作为字典的键,列表则不能。

Q:如何检查一个元素是否存在于容器中?
A:可以使用in关键字检查元素是否存在于列表、元组、字典或集合中。对于字典,in检查的是键而不是值,如key in my_dict

Q:为什么字典的键必须是不可变类型?
A:字典使用哈希表实现,键的哈希值用于快速查找。如果键是可变的,其哈希值可能会变化,导致无法正确查找。因此,只有不可变类型(如整数、字符串、元组)可以作为字典的键。

Q:集合是无序的,这意味着什么?
A:集合的无序性意味着元素没有固定的顺序,不能通过索引访问,且每次遍历的顺序可能不同。如果你需要有序且唯一的元素,可以使用collections模块中的OrderedDict(对于键值对)或手动维护一个列表和集合的组合。

Q:如何高效地遍历容器类型?
A:对于列表和元组,可以直接使用for item in container;对于字典,可以使用for key in my_dict遍历键,for value in my_dict.values()遍历值,或for key, value in my_dict.items()同时遍历键和值;对于集合,使用for item in my_set遍历元素。

🏁 本节总结

  • ✅ 列表(list)是有序、可变的元素集合,适合存储需要修改的序列数据
  • ✅ 元组(tuple)是有序、不可变的元素集合,适合存储不希望被修改的数据
  • ✅ 字典(dict)是键值对集合,适合存储关联数据,通过键快速访问
  • ✅ 集合(set)是无序、唯一的元素集合,适合去重和集合运算
  • ✅ 选择容器类型时应考虑数据的有序性、可变性和访问方式等需求
  • ✅ 熟练掌握各种容器类型的操作方法是高效处理数据的基础

尘埃虽微,积之成集;问题虽小,记之为鉴。 雾中低语,心之所向;思绪飘渺,皆可成章。