文章目录
- [Python 中的数据结构](#Python 中的数据结构)
- [一、Python 数据结构总览](#一、Python 数据结构总览)
- 二、序列类型
-
- [1. List](#1. List)
- [2. Tuple](#2. Tuple)
- [3. String](#3. String)
- [4. Range](#4. Range)
- 三、集合类型
-
- [1. Set](#1. Set)
- [2. Frozenset](#2. Frozenset)
- 四、映射类型
-
- [1. Dict](#1. Dict)
- [五、`collections` 模块中的高级数据结构](#五、
collections模块中的高级数据结构) - 六、自定义数据结构(面向对象)
-
- [1. Stack](#1. Stack)
- [2. Queue](#2. Queue)
- [3. 链表](#3. 链表)
- [4. 二叉树](#4. 二叉树)
- [5. 图](#5. 图)
- 七、总结对比表
Python 中的数据结构
一、Python 数据结构总览
Python 内置了丰富的数据结构,可以分为以下几类
| 类型 | 名称 | 是否可变 | 典型用途 |
|---|---|---|---|
| **序列类型 ** | list(列表) |
✅ 可变 | 存储有序数据集合 |
tuple(元组) |
❌ 不可变 | 存储固定的有序数据集合 | |
str(字符串) |
❌ 不可变 | 存储文本数据 | |
range(区间) |
❌ 不可变 | 用于生成整数序列 | |
| **集合类型 ** | set(集合) |
✅ 可变 | 存储无序、不重复元素 |
frozenset(冻结集合) |
❌ 不可变 | 不可修改的集合 | |
| 映射类型 | dict(字典) |
✅ 可变 | 键值对映射结构 |
| 其他容器类型 | deque、Counter、defaultdict、OrderedDict、namedtuple (在 collections 模块中) |
不同 | 特殊功能的数据结构 |
二、序列类型
序列是 Python 最基本、最常用的数据结构。特点是 有序、可索引、可切片。
1. List
定义: 用 [] 定义的有序可变序列。
fruits = ["apple", "banana", "cherry"]
常用操作:
| 操作 | 示例 | 说明 |
|---|---|---|
| 访问元素 | fruits[0] |
索引访问(从 0 开始) |
| 切片 | fruits[1:3] |
获取子列表 |
| 修改 | fruits[1] = "pear" |
修改元素 |
| 添加 | fruits.append("grape") |
在末尾添加 |
| 插入 | fruits.insert(1, "orange") |
在指定位置插入 |
| 删除 | fruits.remove("apple") / del fruits[0] |
按值/索引删除 |
| 排序 | fruits.sort() |
原地排序 |
| 反转 | fruits.reverse() |
原地反转 |
| 统计 | len(fruits) |
元素个数 |
✅ 特点:
- 可变(可以添加、删除、修改元素)
- 元素可以是不同类型(如
[1, "abc", 3.14, [1,2]])
2. Tuple
定义: 用 () 定义的有序、不可变序列。
py
point = (10, 20)
操作与列表类似,但不可修改:
py
print(point[0]) # ✅ 可以访问
# point[0] = 100 # ❌ 报错,不可修改
✅ 特点:
- 不可变,可用于字典键或集合元素;
- 适合存储固定结构的数据(如坐标、RGB 值等);
- 支持 解包(unpacking):
py
x, y = point # x=10, y=20
3. String
定义: 用 '' 或 "" 或 ''' ''' 定义的不可变字符序列。
py
text = "Hello Python"
常用操作:
py
text.upper() # 'HELLO PYTHON'
text.lower() # 'hello python'
text.split() # ['Hello', 'Python']
"-".join(["A","B"]) # 'A-B'
text.replace("Python", "World") # 'Hello World'
✅ 特点:
- 不可变;
- 支持切片、拼接;
- 丰富的字符串方法。
4. Range
用于生成一个整数序列,常用于循环。
py
range(5) # 0,1,2,3,4
range(2,10,2) # 2,4,6,8
与 for 配合使用:
py
for i in range(3):
print(i) # 输出 0,1,2
三、集合类型
集合是 无序、元素唯一 的容器。
1. Set
定义:
py
nums = {1, 2, 3, 3, 2}
print(nums) # {1, 2, 3}
常用操作:
| 操作 | 示例 | 说明 |
|---|---|---|
| 添加元素 | nums.add(4) |
|
| 删除元素 | nums.remove(3) |
若不存在则报错 |
| 且(交集) | a & b |
|
| 或(并集) | `a | b` |
| 差集 | a - b |
|
| 对称差 | a ^ b |
✅ 特点:
- 无序(不能索引);
- 元素唯一;
- 适合用于 去重 或 集合运算。
2. Frozenset
不可变集合,用法与 set 类似,但不能修改:
py
a = frozenset([1,2,3])
可作为字典的键或集合的元素。
四、映射类型
1. Dict
定义: 键值对结构 {key: value}
py
person = {"name": "Alice", "age": 25, "city": "Beijing"}
常用操作:
| 操作 | 示例 | 说明 |
|---|---|---|
| 访问 | person["name"] |
获取值 |
| 修改 | person["age"] = 30 |
修改 |
| 新增 | person["gender"] = "F" |
新键值对 |
| 删除 | del person["city"] |
删除键值对 |
| 遍历键 | for k in person: |
遍历 key |
| 遍历值 | for v in person.values(): |
遍历 value |
| 遍历项 | for k,v in person.items(): |
遍历 (key,value) |
| 查询 | "name" in person |
判断键是否存在 |
✅ 特点:
- 键必须唯一、且必须是不可变类型;
- 值可以是任意类型;
- 是 Python 最常用的"关联数组"结构。
五、collections 模块中的高级数据结构
Python 的 collections 模块提供了一系列增强型容器
| 类型 | 说明 | 示例 |
|---|---|---|
deque |
双端队列,支持高效插入删除 | 适合队列或栈结构 |
Counter |
计数器,用于统计元素出现次数 | 适合频率分析 |
defaultdict |
带默认值的字典 | 避免 KeyError |
OrderedDict |
记住插入顺序(Python3.7+ 字典本身也已支持) | 兼容旧代码 |
namedtuple |
命名元组,可通过属性访问 | 可读性更高 |
ChainMap |
多字典组合视图 | 合并配置时常用 |
案例:Counter
py
from collections import Counter
text = "banana"
count = Counter(text)
print(count) # Counter({'a': 3, 'n': 2, 'b': 1})
案例:deque
py
from collections import deque
q = deque([1, 2, 3])
q.appendleft(0)
q.pop()
print(q) # deque([0, 1, 2])
六、自定义数据结构(面向对象)
1. Stack
py
# 1. 栈实现
class Stack:
"""栈 - 后进先出(LIFO)数据结构"""
def __init__(self):
self.items = []
def push(self, item):
"""入栈操作"""
self.items.append(item)
def pop(self):
"""出栈操作"""
if not self.is_empty():
return self.items.pop()
raise IndexError("栈为空,无法执行出栈操作")
def peek(self):
"""查看栈顶元素"""
if not self.is_empty():
return self.items[-1]
raise IndexError("栈为空,无法查看栈顶元素")
def is_empty(self):
"""判断栈是否为空"""
return len(self.items) == 0
def size(self):
"""返回栈的大小"""
return len(self.items)
def __str__(self):
return f"Stack({self.items})"
2. Queue
py
# 2. 队列实现
class Queue:
"""队列 - 先进先出(FIFO)数据结构"""
def __init__(self):
self.items = []
def enqueue(self, item):
"""入队操作"""
self.items.append(item)
def dequeue(self):
"""出队操作"""
if not self.is_empty():
return self.items.pop(0)
raise IndexError("队列为空,无法执行出队操作")
def front(self):
"""查看队首元素"""
if not self.is_empty():
return self.items[0]
raise IndexError("队列为空,无法查看队首元素")
def is_empty(self):
"""判断队列是否为空"""
return len(self.items) == 0
def size(self):
"""返回队列的大小"""
return len(self.items)
def __str__(self):
return f"Queue({self.items})"
3. 链表
py
class Node:
"""链表、树、图等数据结构的基础节点类"""
def __init__(self, data=None):
self.data = data
self.next = None # 用于链表
self.left = None # 用于树
self.right = None # 用于树
self.neighbors = [] # 用于图
# 3. 链表实现
class LinkedList:
"""单向链表实现"""
def __init__(self):
self.head = None
self.length = 0
def append(self, data):
"""在链表末尾添加元素"""
new_node = Node(data)
if self.head is None:
self.head = new_node
else:
current = self.head
while current.next:
current = current.next
current.next = new_node
self.length += 1
def prepend(self, data):
"""在链表头部添加元素"""
new_node = Node(data)
new_node.next = self.head
self.head = new_node
self.length += 1
def delete(self, data):
"""删除链表中第一个匹配的元素"""
if self.head is None:
return
if self.head.data == data:
self.head = self.head.next
self.length -= 1
return
current = self.head
while current.next:
if current.next.data == data:
current.next = current.next.next
self.length -= 1
return
current = current.next
def search(self, data):
"""在链表中查找元素"""
current = self.head
while current:
if current.data == data:
return True
current = current.next
return False
def is_empty(self):
"""判断链表是否为空"""
return self.head is None
def size(self):
"""返回链表的大小"""
return self.length
def __str__(self):
elements = []
current = self.head
while current:
elements.append(str(current.data))
current = current.next
return " -> ".join(elements) if elements else "空链表"
4. 二叉树
py
# 4. 二叉树实现
class BinaryTree:
"""二叉树实现"""
def __init__(self, root_data=None):
self.root = Node(root_data) if root_data is not None else None
def insert(self, data):
"""插入元素到二叉树"""
if self.root is None:
self.root = Node(data)
else:
self._insert_recursive(self.root, data)
def _insert_recursive(self, node, data):
"""递归插入辅助函数"""
if data < node.data:
if node.left is None:
node.left = Node(data)
else:
self._insert_recursive(node.left, data)
else:
if node.right is None:
node.right = Node(data)
else:
self._insert_recursive(node.right, data)
def search(self, data):
"""在二叉树中查找元素"""
return self._search_recursive(self.root, data)
def _search_recursive(self, node, data):
"""递归查找辅助函数"""
if node is None or node.data == data:
return node is not None
if data < node.data:
return self._search_recursive(node.left, data)
return self._search_recursive(node.right, data)
def inorder_traversal(self):
"""中序遍历"""
result = []
self._inorder_recursive(self.root, result)
return result
def _inorder_recursive(self, node, result):
"""中序遍历辅助函数"""
if node:
self._inorder_recursive(node.left, result)
result.append(node.data)
self._inorder_recursive(node.right, result)
def preorder_traversal(self):
"""前序遍历"""
result = []
self._preorder_recursive(self.root, result)
return result
def _preorder_recursive(self, node, result):
"""前序遍历辅助函数"""
if node:
result.append(node.data)
self._preorder_recursive(node.left, result)
self._preorder_recursive(node.right, result)
def postorder_traversal(self):
"""后序遍历"""
result = []
self._postorder_recursive(self.root, result)
return result
def _postorder_recursive(self, node, result):
"""后序遍历辅助函数"""
if node:
self._postorder_recursive(node.left, result)
self._postorder_recursive(node.right, result)
result.append(node.data)
def __str__(self):
return f"二叉树中序遍历: {self.inorder_traversal()}"
5. 图
py
# 5. 图实现
class Graph:
"""图实现 - 使用邻接表"""
def __init__(self):
self.vertices = {}
def add_vertex(self, vertex):
"""添加顶点"""
if vertex not in self.vertices:
self.vertices[vertex] = []
def add_edge(self, vertex1, vertex2, directed=False):
"""添加边,默认为无向图"""
if vertex1 not in self.vertices:
self.add_vertex(vertex1)
if vertex2 not in self.vertices:
self.add_vertex(vertex2)
self.vertices[vertex1].append(vertex2)
if not directed:
self.vertices[vertex2].append(vertex1)
def remove_vertex(self, vertex):
"""删除顶点"""
if vertex in self.vertices:
# 删除该顶点的邻接表
del self.vertices[vertex]
# 从其他顶点的邻接表中删除对该顶点的引用
for v in self.vertices:
if vertex in self.vertices[v]:
self.vertices[v].remove(vertex)
def remove_edge(self, vertex1, vertex2, directed=False):
"""删除边"""
if vertex1 in self.vertices and vertex2 in self.vertices[vertex1]:
self.vertices[vertex1].remove(vertex2)
if not directed and vertex1 in self.vertices[vertex2]:
self.vertices[vertex2].remove(vertex1)
def get_vertices(self):
"""获取所有顶点"""
return list(self.vertices.keys())
def get_edges(self):
"""获取所有边"""
edges = []
for vertex in self.vertices:
for neighbor in self.vertices[vertex]:
edges.append((vertex, neighbor))
return edges
def dfs(self, start_vertex):
"""深度优先搜索"""
visited = set()
result = []
self._dfs_recursive(start_vertex, visited, result)
return result
def _dfs_recursive(self, vertex, visited, result):
"""DFS递归辅助函数"""
visited.add(vertex)
result.append(vertex)
for neighbor in self.vertices[vertex]:
if neighbor not in visited:
self._dfs_recursive(neighbor, visited, result)
def bfs(self, start_vertex):
"""广度优先搜索"""
visited = set()
queue = Queue()
result = []
visited.add(start_vertex)
queue.enqueue(start_vertex)
while not queue.is_empty():
vertex = queue.dequeue()
result.append(vertex)
for neighbor in self.vertices[vertex]:
if neighbor not in visited:
visited.add(neighbor)
queue.enqueue(neighbor)
return result
def __str__(self):
result = "图结构:\n"
for vertex in self.vertices:
result += f"{vertex}: {self.vertices[vertex]}\n"
return result
测试代码
py
if __name__ == "__main__":
# 测试栈
print("\n1. 栈测试:")
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)
print(f"栈内容: {stack}")
print(f"栈顶元素: {stack.peek()}")
print(f"出栈: {stack.pop()}")
print(f"出栈后栈内容: {stack}")
# 测试队列
print("\n2. 队列测试:")
queue = Queue()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
print(f"队列内容: {queue}")
print(f"队首元素: {queue.front()}")
print(f"出队: {queue.dequeue()}")
print(f"出队后队列内容: {queue}")
# 测试链表
print("\n3. 链表测试:")
linked_list = LinkedList()
linked_list.append(1)
linked_list.append(2)
linked_list.append(3)
linked_list.prepend(0)
print(f"链表内容: {linked_list}")
print(f"查找元素2: {linked_list.search(2)}")
linked_list.delete(2)
print(f"删除元素2后: {linked_list}")
# 测试二叉树
print("\n4. 二叉树测试:")
tree = BinaryTree()
tree.insert(5)
tree.insert(3)
tree.insert(7)
tree.insert(2)
tree.insert(4)
tree.insert(6)
tree.insert(8)
print(f"二叉树: {tree}")
print(f"前序遍历: {tree.preorder_traversal()}")
print(f"中序遍历: {tree.inorder_traversal()}")
print(f"后序遍历: {tree.postorder_traversal()}")
print(f"查找元素4: {tree.search(4)}")
print(f"查找元素9: {tree.search(9)}")
# 测试图
print("\n5. 图测试:")
graph = Graph()
graph.add_vertex('A')
graph.add_vertex('B')
graph.add_vertex('C')
graph.add_vertex('D')
graph.add_edge('A', 'B')
graph.add_edge('A', 'C')
graph.add_edge('B', 'D')
graph.add_edge('C', 'D')
print(graph)
print(f"所有顶点: {graph.get_vertices()}")
print(f"所有边: {graph.get_edges()}")
print(f"从A开始的DFS: {graph.dfs('A')}")
print(f"从A开始的BFS: {graph.bfs('A')}")
七、总结对比表
| 类型 | 有序性 | 可变性 | 是否允许重复 | 常见用途 |
|---|---|---|---|---|
| list | ✅ | ✅ | ✅ | 一般数据集合 |
| tuple | ✅ | ❌ | ✅ | 不可变集合 |
| str | ✅ | ❌ | ✅ | 文本数据 |
| set | ❌ | ✅ | ❌ | 去重与集合运算 |
| dict | ❌ | ✅ | 键唯一 | 键值映射 |
| frozenset | ❌ | ❌ | ❌ | 不可变集合 |
| deque | ✅ | ✅ | ✅ | 队列/栈 |
| Counter | ❌ | ✅ | ❌ | 计数统计 |
python学习专栏导航
(1)100天python从入门到拿捏《Python 3简介》
(2)100天python从入门到拿捏《python应用前景》
(3)100天python从入门到拿捏《数据类型》
(4)100天python从入门到拿捏《运算符》
(5)100天python从入门到拿捏《流程控制语句》
(6)100天python从入门到拿捏《推导式》
(7)100天python从入门到拿捏《迭代器和生成器》
(8)100天python从入门到拿捏《函数和匿名函数》
(9)100天python从入门到拿捏《装饰器》