AI 学院 · Python 入门线 · 节点 ② / ⑨

数据结构与字符串

手把手教程:把数据组织成列表、字典、集合,把文本玩出花来。约 6-8 个番茄,学完做出一个「词频统计器」才算过。

状态 进行中 前置 ① 基础语法 下一步 ③ 函数与模块

第 0 步 · 一句话地图

数据结构 = 装数据的容器。Python 四种内置容器,各有脾气:

选容器的口诀:要顺序 → list;怕被改 → tuple;要按名字查 → dict;要去重/找共同 → set。

第 1 步 · 字符串(文本的十八般武艺)

字符串是不可变的——方法都返回字符串,原串不动。

1.1 拆与拼(split / join)—— 最常用的一对

sentence = "hello world python"
words = sentence.split()            # 按空白拆 → ['hello','world','python']
words = sentence.split(",")       # 按逗号拆 → ['hello world python'] 没逗号就整串
back = " ".join(words)         # 用空格拼回去 → "hello world python"
split/join 是数据处理的命门:读 CSV、切日志、拼 SQL 全用它俩。看到 "," 分隔的数据第一反应就是 split。

1.2 清理与查找(strip / replace / find / startswith)

raw = "    hello,world  "
clean = raw.strip()                  # 去掉首尾空白 → "hello,world"
clean = clean.replace(",", " ")  # → "hello world"
clean.startswith("he")           # True(前缀判断)
clean.endswith("ld")             # True(后缀判断)
clean.find("wor")                # 6(下标;找不到返回 -1)
clean.upper(); clean.lower()      # 大写 / 小写
用户输入永远带着脏东西:多空格、大小写不一、末尾换行。真实程序第一步几乎都是 strip() + lower()

1.3 切片(slicing)—— 字符串和列表通用

s = "python"
s[0]       # 'p'(下标从 0 开始)
s[-1]      # 'n'(-1 是最后一个)
s[0:3]    # 'pyt'(含头不含尾)
s[1:5:2]  # 'yh'(步长 2)
s[::-1]   # 'nohtyp'(反转,经典技巧)

第 2 步 · 列表(有序、可改)

2.1 增删改查

tasks = ["读书", "运动"]
tasks.append("写代码")      # 尾部加 → ['读书','运动','写代码']
tasks.insert(1, "冥想")    # 插到下标 1 → ['读书','冥想','运动','写代码']
tasks.remove("运动")      # 按值删(只删第一个匹配)
popped = tasks.pop()        # 尾部弹出并返回 → '写代码'
tasks[0] = "精读"          # 按下标改
len(tasks)                    # 长度
"读书" in tasks              # True(成员判断)

2.2 排序

scores = [72, 88, 91, 65]
scores.sort()                  # 原地升序 → [65,72,88,91]
scores.sort(reverse=True)    # 降序
sorted(scores)                # 不改变原列表,返回新列表(更安全)
sort() vs sorted()list.sort() 原地改(省内存);sorted(列表) 返回新列表(不污染原数据)。数据要复用就用 sorted。

2.3 循环遍历(for 的正式用法)

for task in tasks:
    print(f"- {task}")

for i, task in enumerate(tasks):    # 同时拿下标和值
    print(i, task)

第 3 步 · 元组(不可变的"定版")

point = (31.2, 121.5)     # 经纬度
x, y = point                # 解包 unpack:x=31.2, y=121.5
point[0]                    # 31.2 可以读
point[0] = 32               # ❌ TypeError:元组不能改
元组的价值在"防手滑":函数返回多个值时用元组(return x, y 就是返回元组)。配置常量、坐标、日期这类"定了就不该变"的数据用元组。

第 4 步 · 字典(按名字查)

4.1 基础操作

student = {"name": "丢丢", "age": 6, "subjects": ["数学", "英语"]}
student["name"]              # '丢丢'(按键取值,键不存在 → KeyError)
student.get("height", 0)  # 0(安全取值:没有就返回默认)
student["age"] = 7          # 改
student["city"] = "南京"     # 新增键
del student["city"]         # 删键
"name" in student           # True(判断键存在)

4.2 遍历字典

scores = {"数学": 92, "英语": 88, "AI": 95}
for subject, score in scores.items():
    print(f"{subject}: {score}")

scores.keys()    # 所有键
scores.values()  # 所有值
字典是"统计"的天然容器:词频、计数、分组全用 dict。计数模式 d[key] = d.get(key, 0) + 1 会反复出现,现在记住它。

第 5 步 · 集合(去重与关系运算)

a = {1, 2, 3, 3, 3}          # {1,2,3} 自动去重
b = set([3, 4, 5])          # 从列表建集合
a & b     # {3} 交集(共同)
a | b     # {1,2,3,4,5} 并集(全部)
a - b     # {1,2} 差集(a 有 b 没有)
列表去重一行版list(set(列表))。但注意集合无序——顺序不重要时才用它去重。

第 6 步 · 列表推导式(一行生成列表)

squares = [n * n for n in range(1, 6)]       # [1,4,9,16,25]
evens = [n for n in range(10) if n % 2 == 0]  # [0,2,4,6,8] 带条件
words = [w.upper() for w in input("词:").split()]  # 处理输入
推导式 = for 循环的"表达式化":读法「对每个 n 在 range 里,算 n*n」。能一行写完就别写三行;但嵌套超过两层就拆开,可读性优先。

第 7 步 · 实战项目:词频统计器

需求:输入一段英文文本,输出出现次数最多的 5 个词(忽略大小写与标点)。——这是文本分析的第一课,也是以后做 RAG、做语料处理的地基。

Step 1:清洗文本(标点→空格、统一小写)

text = input("粘贴英文文本:")
for ch in ".,!?;:\"'()":          # 逐个标点替换为空格
    text = text.replace(ch, " ")
words = text.lower().split()     # 小写 + 按空白拆

Step 2:计数(字典的经典用法)

count = {}
for w in words:
    count[w] = count.get(w, 0) + 1    # 计数模式:没有就 0 再 +1

Step 3:排序取前 5

top = sorted(count.items(), key=lambda x: x[1], reverse=True)[:5]
# items() → [(词,次数),...];key=lambda x: x[1] 按次数排;[:5] 取前 5
for word, n in top:
    print(f"{word}: {n} 次")
lambda 先不用深究——它就是"临时小函数",lambda x: x[1] 意思是"给我 x,我返回 x 的第 1 项"。节点 ③ 会正式学函数。
扩展(推荐做):过滤掉停用词(the/a/and…);按词长过滤(只统计 ≥4 字母的词);支持中文分词前先把这段英文跑通。

第 8 步 · 报错手册(本节点新增)

1. IndexError: list index out of range —— 下标超出长度(空列表取 [0])。修法:先 len(列表) 或判空 if not 列表
2. KeyError: 'xxx' —— 字典里没有这个键。修法:用 .get(键, 默认值) 或先 if 键 in 字典
3. AttributeError: 'str' object has no attribute 'split' —— 对象类型不对(数字调了字符串方法)。修法type(变量) 确认类型。
4. 排序结果不对 —— 数字列表按文本排序([10, 9, 8] 排成 [10, 8, 9])。修法:确认元素是 int 不是 str,必要时 int() 转换。

节点自测清单

全勾 → 节点 ② 完成,进入节点 ③(函数与模块)。未勾 → 回看对应步骤。

推荐资料