跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Python算法

Python 数据结构详解:序列与集合

综述由AI生成详细讲解了 Python 核心数据结构,包括字符串、列表、字典、集合和元组。重点阐述了可变与不可变对象的区别及其影响,涵盖了索引切片、常用方法、推导式及浅拷贝陷阱等关键知识点。通过代码示例展示了各数据结构的创建、操作及最佳实践,帮助开发者高效组织和管理数据。

孤勇者发布于 2026/3/21更新于 2026/5/2427 浏览
Python 数据结构详解:序列与集合

Python 数据结构详解:序列与集合

引言:数据需要'容器'

上一章我们学会了 Python 的基本语法,能定义变量、处理简单的数字和字符串。但现实世界的数据远不止单个值——比如一个班级的学生名单、商品的库存信息、网站的访问日志……这些都需要用数据结构来组织和存储。

Python 内置了多种强大的数据结构,它们就像不同形状的容器,有的能装一串有序的东西(列表),有的能通过名字快速查找(字典),有的能保证元素唯一(集合)。掌握它们,你的编程能力将瞬间提升一个档次。

本章我们就来逐个击破:字符串(深入)、列表、字典、集合、元组,并理解一个核心概念——可变与不可变。

一、可变与不可变:理解对象的'性格'

在深入具体数据结构之前,先搞清楚一个关键问题:对象能不能被修改?

  • 不可变对象:创建后内容不能改变。一旦修改,Python 会创建一个新对象。
  • 可变对象:创建后内容可以原地修改,内存地址不变。
# 不可变:整数
a = 10
print(id(a))  # 某个地址
a += 1
print(id(a))  # 地址变了,因为创建了新整数

# 可变:列表
lst = [1, 2, 3]
print(id(lst))  # 地址 A
lst.append(4)
print(id(lst))  # 地址 A(没变)

理解这个对后续学习至关重要,因为可变对象的方法往往没有返回值(就地修改),而不可变对象的方法会返回新对象。

二、字符串(深入):不只是文本

第一章我们学会了字符串的基本操作,现在给它来一次'深度体检'。记住:字符串是不可变序列,所以所有'修改'操作都是返回新字符串。

1. 索引与切片(序列通用操作)

字符串里的每个字符都有位置(索引),从 0 开始。

s = "Python"
print(s[0])      # P
print(s[-1])     # n(负数表示从右往左)

切片:[start:stop:step] 截取子串(含 start,不含 stop)

s = "Hello, Python"
print(s[7:13])   # Python
print(s[:5])     # Hello(省略 start 表示从头)
print(s[7:])     # Python(省略 stop 表示到尾)
print(s[::2])    # Hlo yhn(步长为 2)
print(s[::-1])   # nohtyP ,olleH(反转字符串)

2. 常用方法(挑几个最实用的)

方法作用示例
split()按分隔符拆成列表"a,b,c".split(",") → ['a','b','c']
join()将列表合并为字符串"-".join(['a','b','c']) → "a-b-c"
replace()替换子串"Hello world".replace("world","Python") → "Hello Python"
strip()去除两端空白字符" hello ".strip() → "hello"
upper()/lower()大小写转换"Python".upper() → "PYTHON"
startswith()/endswith()判断开头/结尾"hello.py".endswith(".py") → True
find()/index()查找子串位置"hello".find("l") → 2(找不到返回 -1);index() 找不到抛异常
count()统计出现次数"abracadabra".count("a") → 5

冷知识:split() 如果不给参数,会按任意空白字符分割(空格、换行、制表符),并且会压缩连续空白。而 split(' ') 则只按单个空格分割。

3. 字符串格式化:让输出更优雅

老派写法:% 格式化(类似 C 语言)
name = "Alice"
age = 25
print("我是 %s,今年 %d 岁"%(name, age))
中年写法:str.format()
print("我是 {},今年 {} 岁".format(name, age))
print("我是 {name},今年 {age} 岁".format(name=name, age=age))
现代写法:f-string(Python 3.6+ 推荐)
print(f"我是 {name},今年 {age} 岁")
print(f"3.14159 保留两位小数:{3.14159:.2f}")  # 3.14

f-string 简洁直观,还能在花括号里写表达式,必学!

三、列表:Python 的'万能背包'

列表是可变序列,能装任意类型的数据(甚至可以混合类型),用方括号 [] 表示。

1. 创建列表

fruits = ["apple", "banana", "orange"]
mixed = [1, "hello", 3.14, True]
empty = []  # 空列表
list_from_str = list("Python")  # ['P', 'y', 't', 'h', 'o', 'n']

列表推导式(快速生成列表的优雅写法):

squares = [x**2 for x in range(10)]  # [0, 1, 4, 9, ..., 81]
evens = [x for x in range(20) if x % 2 == 0]

2. 常用方法(可变对象的'动作')

方法作用示例(假设 lst = [1, 2, 3])
append(x)末尾添加一个元素lst.append(4) → [1,2,3,4]
extend(iterable)末尾添加多个元素lst.extend([4,5]) → [1,2,3,4,5]
insert(i, x)在 i 位置插入 xlst.insert(1, 99) → [1,99,2,3]
remove(x)删除第一个值为 x 的元素lst.remove(2) → [1,3]
pop([i])删除并返回 i 位置元素(默认末尾)lst.pop() → 3,列表变为 [1,2]
clear()清空列表lst.clear() → []
index(x)返回第一个 x 的索引[1,2,3].index(2) → 1
count(x)统计 x 出现次数[1,2,2,3].count(2) → 2
sort()原地排序[3,1,2].sort() → [1,2,3]
reverse()原地反转[1,2,3].reverse() → [3,2,1]
copy()返回浅拷贝new_lst = lst.copy()

⚠️ 注意:append 和 extend 的区别:

lst = [1, 2]
lst.append([3, 4])  # [1, 2, [3, 4]]
lst.extend([5, 6])  # [1, 2, [3, 4], 5, 6]

3. 索引与切片(可读可写)

列表的切片不仅可读,还可赋值修改(这是可变性的体现)。

lst = [10, 20, 30, 40, 50]
print(lst[1:4])  # [20, 30, 40]
lst[1:4] = [99, 100]  # 替换切片内容
print(lst)  # [10, 99, 100, 50]

删除元素/切片:del

del lst[1]  # 删除索引 1 的元素
del lst[1:3]  # 删除切片

拼接:+ 和 *(返回新列表,不修改原列表)

print([1, 2] + [3, 4])  # [1, 2, 3, 4]
print([0] * 5)          # [0, 0, 0, 0, 0]

4. 列表的'坑':浅拷贝

列表的 copy() 或 [:] 是浅拷贝——只复制外层容器,内层元素还是引用。如果列表里包含可变对象(比如另一个列表),修改内层会影响拷贝。

a = [1, [2, 3]]
b = a.copy()
b[0] = 100  # 修改外层,不影响 a
b[1][0] = 999  # 修改内层,a 也被改了!
print(a)  # [1, [999, 3]]

要完全独立需用 copy.deepcopy。

四、字典:快速查找的'通讯录'

字典是可变映射,存储键值对,用花括号 {} 表示。键必须是不可变类型(如字符串、数字、元组),值可以是任意对象。

1. 创建字典

person = {"name": "Alice", "age": 25, "city": "New York"}
empty_dict = {}
dict_from_pairs = dict([("name", "Bob"), ("age", 30)])
dict_with_keywords = dict(name="Charlie", age=35)

字典推导式:

squares_dict = {x: x**2 for x in range(5)}  # {0:0, 1:1, 2:4, 3:9, 4:16}

2. 访问与修改

print(person["name"])  # Alice
print(person.get("gender", "未知"))  # 键不存在返回默认值,不会抛 KeyError
person["age"] = 26  # 修改
person["gender"] = "female"  # 新增键值对
person.update({"city": "Boston", "job": "engineer"})  # 批量更新

3. 删除

del person["gender"]  # 删除指定键
age = person.pop("age")  # 删除并返回该键的值
last_item = person.popitem()  # 删除并返回最后一个键值对(Python 3.7+ 有序)
person.clear()  # 清空

4. 视图:keys()、values()、items()

返回动态视图,会随字典变化而变化。

d = {"a": 1, "b": 2}
print(d.keys())    # dict_keys(['a', 'b'])
print(d.values())  # dict_values([1, 2])
print(d.items())   # dict_items([('a', 1), ('b', 2)])
# 常用循环
for k, v in d.items():
    print(k, v)

5. 冷知识:字典从 Python 3.7 开始有序了!

以前字典是无序的,现在会保持插入顺序。但别依赖排序来做什么——想排序请用 sorted()。

6. 默认值:collections.defaultdict(选读)

如果想在访问不存在的键时自动生成默认值,可以用 defaultdict:

from collections import defaultdict
dd = defaultdict(int)  # 默认值 0
dd["count"] += 1  # 不会报错
print(dd)  # {'count': 1}

五、集合:去重与集合运算的高手

集合是可变无序集,元素必须唯一且不可变(所以不能放列表)。用花括号 {} 表示,但空集要用 set()。

1. 创建集合

s = {1, 2, 3}
empty_set = set()  # 注意 {} 是空字典
from_list = set([1, 2, 2, 3])  # {1, 2, 3} 自动去重

集合推导式:

squares_set = {x**2 for x in range(5)}  # {0, 1, 4, 9, 16}

2. 修改集合

方法作用示例
add(x)添加元素s.add(4)
remove(x)删除 x,不存在抛 KeyErrors.remove(2)
discard(x)删除 x,不存在不报错s.discard(100)
pop()随机删除并返回一个元素s.pop()
clear()清空s.clear()

3. 集合运算(数学课代表上线)

假设 a = {1, 2, 3},b = {2, 3, 4}

运算符号方法结果
并集``a.union(b)
交集&a.intersection(b){2, 3}
差集-a.difference(b){1}
对称差^a.symmetric_difference(b){1, 4}

子集判断:

{1, 2}.issubset({1, 2, 3})  # True,也可以用 <=
{1, 2, 3}.issuperset({1, 2})  # True,也可以用 >=

4. 不可变版本:frozenset

如果你需要一个不能修改的集合(比如作为字典的键),可以用 frozenset:

fs = frozenset([1, 2, 3])
# fs.add(4)  # 报错

六、元组:不可变的'列表'

元组是不可变序列,用圆括号 () 表示。一旦创建,不能增删改元素。

1. 创建元组

t = (1, 2, 3)
single = (1,)  # 单元素必须加逗号,否则 (1) 就是整数 1
empty = ()
from_list = tuple([4, 5, 6])

2. 不可变?等等,有陷阱!

元组的不可变是指元素的引用不可变。如果元素本身是可变对象,那它的内容还是可以变的。

t = (1, [2, 3])
t[1].append(4)  # 合法!t 变成 (1, [2, 3, 4])
# t[0] = 100  # 报错,不能修改元组本身

3. 解包(元组最实用的特性)

point = (10, 20)
x, y = point  # x=10, y=20
a, b, c = (1, 2, 3)

甚至可以用 * 收集多余元素:

first, *rest = (1, 2, 3, 4)  # first=1, rest=[2, 3, 4]

4. 方法:只有两个

t = (1, 2, 2, 3)
print(t.count(2))  # 2
print(t.index(3))  # 3

5. 命名元组(选读)

collections.namedtuple 可以创建带字段名的元组,像轻量级对象:

from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
p = Point(10, 20)
print(p.x, p.y)  # 10 20

本章总结

数据结构类型可变?特点常用场景
字符串序列❌ 不可变文本处理几乎所有程序
列表序列✅ 可变万能容器,有序存储任意序列
元组序列❌ 不可变轻量,可哈希固定数据,函数返回多值
字典映射✅ 可变键值对,快速查找结构化数据,缓存
集合集合✅ 可变元素唯一,集合运算去重,关系判断

记住:

  • 列表用 [],元组用 (),字典用 {}(键值对),集合也用 {}(但元素单一)
  • 可变对象的方法通常就地修改,不可变对象的方法返回新对象
  • 能用元组就用元组(更安全、更轻量)

目录

  1. Python 数据结构详解:序列与集合
  2. 引言:数据需要“容器”
  3. 一、可变与不可变:理解对象的“性格”
  4. 不可变:整数
  5. 可变:列表
  6. 二、字符串(深入):不只是文本
  7. 1. 索引与切片(序列通用操作)
  8. 2. 常用方法(挑几个最实用的)
  9. 3. 字符串格式化:让输出更优雅
  10. 老派写法:% 格式化(类似 C 语言)
  11. 中年写法:str.format()
  12. 现代写法:f-string(Python 3.6+ 推荐)
  13. 三、列表:Python 的“万能背包”
  14. 1. 创建列表
  15. 2. 常用方法(可变对象的“动作”)
  16. 3. 索引与切片(可读可写)
  17. 4. 列表的“坑”:浅拷贝
  18. 四、字典:快速查找的“通讯录”
  19. 1. 创建字典
  20. 2. 访问与修改
  21. 3. 删除
  22. 4. 视图:keys()、values()、items()
  23. 常用循环
  24. 5. 冷知识:字典从 Python 3.7 开始有序了!
  25. 6. 默认值:collections.defaultdict(选读)
  26. 五、集合:去重与集合运算的高手
  27. 1. 创建集合
  28. 2. 修改集合
  29. 3. 集合运算(数学课代表上线)
  30. 4. 不可变版本:frozenset
  31. fs.add(4) # 报错
  32. 六、元组:不可变的“列表”
  33. 1. 创建元组
  34. 2. 不可变?等等,有陷阱!
  35. t[0] = 100 # 报错,不能修改元组本身
  36. 3. 解包(元组最实用的特性)
  37. 4. 方法:只有两个
  38. 5. 命名元组(选读)
  39. 本章总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 基于MATLAB的三维A星算法无人机导航与路径规划
  • Flood Fill 算法详解:DFS/BFS 实现与经典应用
  • Python AI 入门与学习路线指南
  • 基于 Segment Anything 模型的图像分割部署与测试
  • VS Code 集成 Git 安装与配置实战指南
  • RoboChallenge 发布具身智能年度报告:4 万次真机评测揭示模型真实水平
  • Flutter 适配鸿蒙:BIP340 Schnorr 签名应用实践
  • GPU/TPU/FPGA 异构算力成本健康度审计与优化实践
  • Qwen3-VL-WEB 可视化工具使用指南与竞品分析实战
  • Windows 环境 Git 安装与配置指南
  • 人工智能:自然语言处理与计算机视觉融合应用
  • Chaterm:AI 驱动的云资源管理终端实战指南
  • FPGA 时序逻辑电路优化技巧实战
  • FFT NPainting LaMa 与 Stable Diffusion Inpainting 性能对比评测
  • SQL 基础与进阶:增删改查、查询优化及约束
  • 基于 Spring Cloud 的分布式智能推荐系统架构与实践
  • 二叉树算法实战:美国血统重建与深度宽度计算
  • 2025 年跨境外贸必备 AI 工具与实战指南
  • Spring 事务管理实战:@Transactional 注解与传播机制深度解析
  • 基于 Document PiP API 实现视频小窗及状态同步

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online