Veloris.
返回索引
概念基础 2026-02-14

列表、字典、元组、集合:Python四大容器类型,一篇搞懂什么时候用哪个

4 分钟
1.2k words

列表、字典、元组、集合:Python四大容器类型,一篇搞懂什么时候用哪个

容器类型是Python中最常用的数据结构,用于存储多个元素。掌握列表、元组、字典、集合的使用是Python编程的基础。本篇将详细介绍这四种容器类型的特性、操作方法,并与C语言的数组进行对比。


1. 容器类型概览

类型有序可变可重复索引方式典型用途
列表 list整数索引存储有序数据集合
元组 tuple整数索引存储不可变的有序数据
字典 dict✅*键不可重复键索引键值对映射
集合 set无索引去重、集合运算

*注:Python 3.7+字典保持插入顺序


2. 列表(list)

列表是Python中最常用的容器类型,类似于C语言的数组,但功能更强大。

2.1 列表的创建

# 空列表
empty_list = []
empty_list = list()

# 带初始值的列表
numbers = [1, 2, 3, 4, 5]
fruits = ["apple", "banana", "cherry"]

# 混合类型(Python允许,C不允许)
mixed = [1, "hello", 3.14, True, None]

# 从其他可迭代对象创建
from_string = list("hello")  # ['h', 'e', 'l', 'l', 'o']
from_range = list(range(5))  # [0, 1, 2, 3, 4]

# 重复元素
zeros = [0] * 5  # [0, 0, 0, 0, 0]
pattern = [1, 2] * 3  # [1, 2, 1, 2, 1, 2]

2.2 列表的索引与切片

fruits = ["apple", "banana", "cherry", "date", "elderberry"]

# 索引访问
print(fruits[0])   # 'apple'(第一个)
print(fruits[-1])  # 'elderberry'(最后一个)
print(fruits[2])   # 'cherry'

# 修改元素
fruits[0] = "apricot"
print(fruits)  # ['apricot', 'banana', 'cherry', 'date', 'elderberry']

# 切片 [start:end:step]
print(fruits[1:3])   # ['banana', 'cherry']
print(fruits[:3])    # ['apricot', 'banana', 'cherry']
print(fruits[2:])    # ['cherry', 'date', 'elderberry']
print(fruits[::2])   # ['apricot', 'cherry', 'elderberry']
print(fruits[::-1])  # 反转列表

# 切片赋值
fruits[1:3] = ["blueberry", "cantaloupe"]
print(fruits)  # ['apricot', 'blueberry', 'cantaloupe', 'date', 'elderberry']

# 切片删除
fruits[1:3] = []
print(fruits)  # ['apricot', 'date', 'elderberry']

2.3 列表的常用方法

# 添加元素
fruits = ["apple", "banana"]
fruits.append("cherry")      # 末尾添加:['apple', 'banana', 'cherry']
fruits.insert(1, "apricot")  # 指定位置插入:['apple', 'apricot', 'banana', 'cherry']
fruits.extend(["date", "elderberry"])  # 扩展列表

# 删除元素
fruits.remove("banana")  # 按值删除(删除第一个匹配项)
item = fruits.pop()      # 弹出末尾元素并返回
item = fruits.pop(0)     # 弹出指定位置元素
del fruits[0]            # 删除指定位置元素
fruits.clear()           # 清空列表

# 查找元素
fruits = ["apple", "banana", "cherry", "banana"]
print(fruits.index("banana"))  # 1(第一个匹配项的索引)
print(fruits.count("banana"))  # 2(出现次数)
print("apple" in fruits)       # True(是否存在)

# 排序
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
numbers.sort()               # 原地排序:[1, 1, 2, 3, 4, 5, 6, 9]
numbers.sort(reverse=True)   # 降序排序
sorted_nums = sorted(numbers)  # 返回新列表,原列表不变

# 自定义排序
words = ["banana", "apple", "Cherry"]
words.sort(key=str.lower)    # 忽略大小写排序
words.sort(key=len)          # 按长度排序

# 反转
numbers.reverse()            # 原地反转
reversed_nums = numbers[::-1]  # 返回新列表

# 复制
copy1 = fruits.copy()        # 浅复制
copy2 = fruits[:]            # 浅复制
copy3 = list(fruits)         # 浅复制

import copy
deep_copy = copy.deepcopy(fruits)  # 深复制(嵌套列表时使用)

2.4 列表推导式

列表推导式是Python的特色语法,可以简洁地创建列表。

# 基本语法:[表达式 for 变量 in 可迭代对象]
squares = [x**2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 带条件:[表达式 for 变量 in 可迭代对象 if 条件]
even_squares = [x**2 for x in range(10) if x % 2 == 0]
# [0, 4, 16, 36, 64]

# 多重循环
matrix = [[i*3+j for j in range(3)] for i in range(3)]
# [[0, 1, 2], [3, 4, 5], [6, 7, 8]]

# 展平嵌套列表
nested = [[1, 2], [3, 4], [5, 6]]
flat = [x for sublist in nested for x in sublist]
# [1, 2, 3, 4, 5, 6]

# 条件表达式
numbers = [1, -2, 3, -4, 5]
abs_nums = [x if x > 0 else -x for x in numbers]
# [1, 2, 3, 4, 5]

# 与传统循环对比
# 传统写法
squares = []
for x in range(10):
    squares.append(x**2)

# 列表推导式
squares = [x**2 for x in range(10)]

2.5 列表与C数组对比

特性C数组Python列表
类型固定类型可混合类型
大小固定大小动态大小
内存连续内存对象引用数组
越界未定义行为抛出异常
操作手动实现内置方法丰富
// C数组
int arr[5] = {1, 2, 3, 4, 5};
arr[0] = 10;
// 无法直接添加元素,需要重新分配内存
# Python列表
arr = [1, 2, 3, 4, 5]
arr[0] = 10
arr.append(6)  # 轻松添加元素

3. 元组(tuple)

元组是不可变的有序序列,一旦创建就不能修改。

3.1 元组的创建

# 空元组
empty_tuple = ()
empty_tuple = tuple()

# 带初始值的元组
point = (3, 4)
colors = ("red", "green", "blue")

# 单元素元组(注意逗号)
single = (1,)    # 正确:元组
not_tuple = (1)  # 错误:这是整数1

# 省略括号
point = 3, 4     # 等价于 (3, 4)
a, b = 1, 2      # 元组解包

# 从其他可迭代对象创建
from_list = tuple([1, 2, 3])
from_string = tuple("hello")  # ('h', 'e', 'l', 'l', 'o')

3.2 元组的特性

point = (3, 4, 5)

# 索引和切片(与列表相同)
print(point[0])    # 3
print(point[-1])   # 5
print(point[1:])   # (4, 5)

# 不可变性
# point[0] = 10  # TypeError: 'tuple' object does not support item assignment

# 元组方法(只有两个)
print(point.count(3))  # 1
print(point.index(4))  # 1

# 元组解包
x, y, z = point
print(x, y, z)  # 3 4 5

# 扩展解包(Python 3)
first, *rest = (1, 2, 3, 4, 5)
print(first)  # 1
print(rest)   # [2, 3, 4, 5]

*start, last = (1, 2, 3, 4, 5)
print(start)  # [1, 2, 3, 4]
print(last)   # 5

# 元组拼接(创建新元组)
t1 = (1, 2)
t2 = (3, 4)
t3 = t1 + t2  # (1, 2, 3, 4)

3.3 元组的应用场景

# 1. 函数返回多个值
def get_min_max(numbers):
    return min(numbers), max(numbers)

min_val, max_val = get_min_max([3, 1, 4, 1, 5])

# 2. 交换变量
a, b = 10, 20
a, b = b, a  # 利用元组解包交换

# 3. 作为字典的键(列表不能作为键)
locations = {
    (0, 0): "origin",
    (1, 0): "right",
    (0, 1): "up"
}

# 4. 保护数据不被修改
WEEKDAYS = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday")

# 5. 命名元组(更清晰的数据结构)
from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])
p = Point(3, 4)
print(p.x, p.y)  # 3 4
print(p[0], p[1])  # 3 4

4. 字典(dict)

字典是键值对的集合,类似于C语言中的哈希表或其他语言的Map。

4.1 字典的创建

# 空字典
empty_dict = {}
empty_dict = dict()

# 带初始值的字典
person = {
    "name": "张三",
    "age": 25,
    "city": "北京"
}

# 使用dict()构造
person = dict(name="张三", age=25, city="北京")

# 从键值对列表创建
items = [("name", "张三"), ("age", 25)]
person = dict(items)

# 使用fromkeys创建
keys = ["a", "b", "c"]
d = dict.fromkeys(keys, 0)  # {'a': 0, 'b': 0, 'c': 0}

4.2 字典的操作

person = {"name": "张三", "age": 25, "city": "北京"}

# 访问值
print(person["name"])       # '张三'
print(person.get("name"))   # '张三'
print(person.get("salary", 0))  # 0(键不存在时返回默认值)

# 修改值
person["age"] = 26

# 添加键值对
person["salary"] = 10000

# 删除键值对
del person["city"]
salary = person.pop("salary")  # 删除并返回值
person.pop("unknown", None)    # 键不存在时返回默认值

# 检查键是否存在
print("name" in person)  # True
print("city" in person)  # False

# 遍历字典
for key in person:
    print(key, person[key])

for key, value in person.items():
    print(f"{key}: {value}")

for key in person.keys():
    print(key)

for value in person.values():
    print(value)

4.3 字典的常用方法

d = {"a": 1, "b": 2}

# 获取所有键、值、键值对
keys = d.keys()      # dict_keys(['a', 'b'])
values = d.values()  # dict_values([1, 2])
items = d.items()    # dict_items([('a', 1), ('b', 2)])

# 更新字典
d.update({"c": 3, "d": 4})
d.update(e=5, f=6)

# 设置默认值
d.setdefault("g", 7)  # 如果键不存在,设置并返回默认值

# 合并字典(Python 3.9+)
d1 = {"a": 1, "b": 2}
d2 = {"c": 3, "d": 4}
d3 = d1 | d2  # {'a': 1, 'b': 2, 'c': 3, 'd': 4}

# Python 3.5+的合并方式
d3 = {**d1, **d2}

# 复制
d_copy = d.copy()  # 浅复制

# 清空
d.clear()

4.4 字典推导式

# 基本语法:{键表达式: 值表达式 for 变量 in 可迭代对象}
squares = {x: x**2 for x in range(5)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# 带条件
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}
# {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}

# 键值互换
original = {"a": 1, "b": 2, "c": 3}
swapped = {v: k for k, v in original.items()}
# {1: 'a', 2: 'b', 3: 'c'}

# 从两个列表创建字典
keys = ["name", "age", "city"]
values = ["张三", 25, "北京"]
person = {k: v for k, v in zip(keys, values)}
# 或使用dict(zip(keys, values))

5. 集合(set)

集合是无序、不重复元素的集合,支持数学集合运算。

5.1 集合的创建

# 空集合(注意:{}是空字典)
empty_set = set()

# 带初始值的集合
numbers = {1, 2, 3, 4, 5}
fruits = {"apple", "banana", "cherry"}

# 自动去重
numbers = {1, 2, 2, 3, 3, 3}
print(numbers)  # {1, 2, 3}

# 从其他可迭代对象创建
from_list = set([1, 2, 2, 3])  # {1, 2, 3}
from_string = set("hello")      # {'h', 'e', 'l', 'o'}

# 不可变集合
frozen = frozenset([1, 2, 3])

5.2 集合的操作

# 添加元素
s = {1, 2, 3}
s.add(4)           # {1, 2, 3, 4}
s.update([5, 6])   # {1, 2, 3, 4, 5, 6}

# 删除元素
s.remove(6)        # 删除指定元素(不存在则报错)
s.discard(10)      # 删除指定元素(不存在不报错)
item = s.pop()     # 随机弹出一个元素
s.clear()          # 清空集合

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

# 并集
print(a | b)           # {1, 2, 3, 4, 5, 6}
print(a.union(b))

# 交集
print(a & b)           # {3, 4}
print(a.intersection(b))

# 差集
print(a - b)           # {1, 2}
print(a.difference(b))

# 对称差集(异或)
print(a ^ b)           # {1, 2, 5, 6}
print(a.symmetric_difference(b))

# 子集和超集
c = {1, 2}
print(c <= a)          # True(c是a的子集)
print(c.issubset(a))
print(a >= c)          # True(a是c的超集)
print(a.issuperset(c))

# 不相交
d = {7, 8}
print(a.isdisjoint(d))  # True(没有共同元素)

5.3 集合的应用场景

# 1. 去重
numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
unique = list(set(numbers))  # [1, 2, 3, 4]

# 2. 成员检测(比列表快)
valid_users = {"alice", "bob", "charlie"}
if "alice" in valid_users:
    print("用户有效")

# 3. 找出两个列表的共同元素
list1 = [1, 2, 3, 4, 5]
list2 = [4, 5, 6, 7, 8]
common = set(list1) & set(list2)  # {4, 5}

# 4. 找出两个列表的不同元素
diff = set(list1) ^ set(list2)  # {1, 2, 3, 6, 7, 8}

# 5. 统计唯一元素个数
text = "hello world"
unique_chars = len(set(text))  # 8(包括空格)

6. 容器类型对比

操作列表 list元组 tuple字典 dict集合 set
创建[1, 2](1, 2){"a": 1}{1, 2}
空容器[](){}set()
添加append()不可变d[k]=vadd()
删除remove()不可变del d[k]remove()
访问lst[i]tup[i]d[k]无索引
长度len()len()len()len()
遍历for x infor x infor k infor x in
成员检测in(慢)in(慢)in(快)in(快)

选择建议

需求推荐类型
有序、可修改的数据集合列表
有序、不可修改的数据元组
键值对映射字典
去重、集合运算集合
函数返回多个值元组
作为字典的键元组(不可变)
快速成员检测集合或字典

7. 嵌套与复杂数据结构

# 嵌套列表(二维数组/矩阵)
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]
print(matrix[1][2])  # 6

# 列表中的字典
students = [
    {"name": "张三", "score": 85},
    {"name": "李四", "score": 92},
    {"name": "王五", "score": 78}
]
print(students[0]["name"])  # 张三

# 字典中的列表
class_info = {
    "class_name": "一班",
    "students": ["张三", "李四", "王五"],
    "scores": [85, 92, 78]
}

# 字典中的字典
company = {
    "name": "ABC公司",
    "departments": {
        "tech": {"head": "张三", "count": 20},
        "sales": {"head": "李四", "count": 15}
    }
}
print(company["departments"]["tech"]["head"])  # 张三

# 实际应用:JSON数据结构
user_data = {
    "id": 1001,
    "name": "张三",
    "contacts": {
        "email": "[email protected]",
        "phone": ["13800138000", "13900139000"]
    },
    "orders": [
        {"id": "A001", "amount": 100.0},
        {"id": "A002", "amount": 200.0}
    ]
}

8. 常见错误与避坑

❌ 错误1:列表作为默认参数

# 错误:可变对象作为默认参数
def add_item(item, lst=[]):
    lst.append(item)
    return lst

print(add_item(1))  # [1]
print(add_item(2))  # [1, 2](不是[2]!)

# 正确:使用None作为默认值
def add_item(item, lst=None):
    if lst is None:
        lst = []
    lst.append(item)
    return lst

❌ 错误2:浅复制陷阱

# 浅复制:嵌套对象共享引用
original = [[1, 2], [3, 4]]
shallow = original.copy()
shallow[0][0] = 100
print(original)  # [[100, 2], [3, 4]](原列表也被修改!)

# 深复制:完全独立
import copy
deep = copy.deepcopy(original)
deep[0][0] = 999
print(original)  # [[100, 2], [3, 4]](原列表不变)

❌ 错误3:遍历时修改列表

# 错误:遍历时删除元素
numbers = [1, 2, 3, 4, 5]
for n in numbers:
    if n % 2 == 0:
        numbers.remove(n)  # 可能跳过元素

# 正确:遍历副本或使用列表推导式
numbers = [1, 2, 3, 4, 5]
numbers = [n for n in numbers if n % 2 != 0]

❌ 错误4:字典键不存在

d = {"a": 1}

# 错误:直接访问不存在的键
# print(d["b"])  # KeyError

# 正确:使用get()或检查
print(d.get("b", 0))  # 0
if "b" in d:
    print(d["b"])

❌ 错误5:集合元素必须可哈希

# 错误:列表不能作为集合元素
# s = {[1, 2], [3, 4]}  # TypeError

# 正确:使用元组
s = {(1, 2), (3, 4)}

9. 实战练习

练习1:列表操作

"""
练习:学生成绩管理
"""
scores = [85, 92, 78, 96, 88, 73, 91, 82]

# 1. 计算平均分
average = sum(scores) / len(scores)
print(f"平均分:{average:.2f}")

# 2. 找出最高分和最低分
print(f"最高分:{max(scores)}")
print(f"最低分:{min(scores)}")

# 3. 统计及格人数(>=60)
pass_count = len([s for s in scores if s >= 60])
print(f"及格人数:{pass_count}")

# 4. 按成绩排序
sorted_scores = sorted(scores, reverse=True)
print(f"成绩排名:{sorted_scores}")

练习2:字典操作

"""
练习:单词频率统计
"""
text = "hello world hello python world python python"
words = text.split()

# 统计词频
word_count = {}
for word in words:
    word_count[word] = word_count.get(word, 0) + 1

print(word_count)
# {'hello': 2, 'world': 2, 'python': 3}

# 使用Counter(更简洁)
from collections import Counter
word_count = Counter(words)
print(word_count.most_common(2))  # [('python', 3), ('hello', 2)]

练习3:集合操作

"""
练习:找出两个班级的共同学生和各自独有学生
"""
class_a = {"张三", "李四", "王五", "赵六", "钱七"}
class_b = {"王五", "赵六", "孙八", "周九", "吴十"}

# 共同学生
common = class_a & class_b
print(f"共同学生:{common}")

# A班独有
only_a = class_a - class_b
print(f"A班独有:{only_a}")

# B班独有
only_b = class_b - class_a
print(f"B班独有:{only_b}")

# 所有学生
all_students = class_a | class_b
print(f"所有学生:{all_students}")

10. 总结

🔑 核心要点

知识点要点
列表有序可变,支持索引切片,方法丰富
元组有序不可变,可作为字典键
字典键值对映射,键必须可哈希
集合无序不重复,支持集合运算
推导式简洁创建列表/字典/集合
深浅复制嵌套结构需注意深复制

✅ 学习检查清单

  • 掌握列表的创建、索引、切片、常用方法
  • 理解列表推导式的语法
  • 理解元组的不可变性和应用场景
  • 掌握字典的创建和操作
  • 掌握集合的创建和集合运算
  • 理解深浅复制的区别
  • 能根据需求选择合适的容器类型

📖 下一步学习

掌握了容器类型后,让我们学习Python的运算符与表达式:


常见问题 FAQ

💬 列表和元组怎么选?

需要修改用列表,不需要修改用元组。元组更省内存、可以做字典的key、作为函数返回多个值很方便。

💬 字典是有序的吗?

Python 3.7+字典保持插入顺序。但如果你需要排序功能,用collections.OrderedDict更明确。


📘 系列导航

End of file.