码上问学问代码之理,学编程之道

第 2 章 · 语法核心

这一章把“和电脑对话”的词汇量真正攒起来:字符串、列表、字典、条件判断、循环、函数。它们是所有 Python 程序的积木,也是后面数据处理与自动化的地基。

字符串与编码

先讲为什么程序里绝大部分“真实世界数据”都是文字:姓名、地址、日志、网页内容……字符串就是装文字的容器。而“编码”解决的是“中文/英文在电脑里到底怎么存”的老问题——Python 3 默认用 UTF-8,中文不再乱码。
string.pypython可运行
s = "码上问学"
print(len(s))          # 长度:4(一个中文字算一个字符)
print(s[0])            # 取第 1 个字符:码
print(s[0:2])          # 切片:取前 2 个 → 码上

# 常用“整理文字”的方法
print("  hello  ".strip())   # 去掉两端空格 → hello
print("a-b-c".split("-"))     # 按 - 切开 → ['a','b','c']
print("-".join(["x","y"]))    # 用 - 连接 → x-y
print("Python".lower())       # 转小写 → python
运行输出Python 运行结果
运行结果: 4 码 码上 hello ['a', 'b', 'c'] x-y python
讲透
  • 索引从 0 开始:s[0] 是第一个字符,这是几乎所有编程语言的约定。
  • 切片 s[a:b] 取“从 a 到 b 之前”,左闭右开,所以 s[0:2] 取第 0、1 个。
  • 字符串方法(len / strip / split)都不会“改掉原字符串”,而是返回一个新的——字符串在 Python 里是不可变的。
  • 后面第 3 章会专门讲“切片”这件神器,这里先认识它。
string2.pypython可运行
# 转义字符:\n 换行、\t 制表符
print("第一行\n第二行")
print("姓名\t年龄")        # \t 把两列对齐

# 原始字符串 r"...":反斜杠不当转义,写文件路径 / 正则最方便
print(r"C:\Users\name\file")

# f-string:把变量直接嵌进字符串,最推荐的格式化写法
name, score = "李华", 92
print(f"{name} 考了 {score} 分,评价:{'优秀' if score >= 90 else '良好'}")

# 编码:文字 ⇄ 字节(网络传输、存文件时要用)
b = "码上问学".encode("utf-8")
print(b)                  # 一串字节
print(b.decode("utf-8"))  # 字节还原成文字
运行输出Python 运行结果
运行结果: 第一行 第二行 姓名 年龄 C:\Users\name\file 李华 考了 92 分,评价:优秀 b'\xe7\xa0\x81\xe4\xb8\x8a\xe9\x97\xae\xe5\xad\xa6' 码上问学
避坑字符串是不可变的:想改其中某个字,不能直接 s[0] = "新"(会报 TypeError)。正确做法是“切片 + 拼接”生成新串,例如 s = s[1:] + "新"。记住:所有字符串方法都返回新串,原串不变。

列表与元组:装一串数据的盒子

四个「装数据的容器」:列表能改、元组锁死、字典按键查、集合去重list 列表 [ ]有序 · 可增删改例:购物清单、成绩单tuple 元组 ( )有序 · 只读例:坐标、固定配置dict 字典 {k:v}键值对 · 按键取例:一个用户的信息set 集合 { }无序 · 自动去重例:标签、去重选型口诀:要改用 list,锁死用 tuple,按键查用 dict,去重用 set
动手做列表 list 用 [ ] 表示,能装任意多个、任意类型的数据,还能随时增删改。tuple(元组)用 ( ),一旦定好就不能改——适合“固定不变的一组值”,比如经纬度。
list.pypython可运行
scores = [88, 92, 75, 100]
scores.append(60)      # 追加一个元素
scores[0] = 90         # 改第 1 个
print(scores)
print("最高分:", max(scores))
print("平均分:", sum(scores) / len(scores))

point = (116.4, 39.9)  # 元组:北京经纬度,定好不改
print("经度", point[0], "纬度", point[1])
运行输出Python 运行结果
运行结果: [90, 92, 75, 100, 60] 最高分: 100 平均分: 83.4 经度 116.4 纬度 39.9
讲透max / sum / len 都是内置函数,直接作用于列表。“平均分 = 总和 ÷ 个数”这一步看似简单,却是所有数据统计的缩影;第 4 章我们会用 pandas 让这件事变成一行。
list2.pypython可运行
fruits = ["苹果", "香蕉", "橙子"]
fruits.insert(1, "西瓜")     # 在位置 1 插入
print(fruits)                # ['苹果', '西瓜', '香蕉', '橙子']
last = fruits.pop()          # 删最后一个并返回它
print("pop 出:", last, ",剩下:", fruits)

matrix = [[1, 2, 3], [4, 5, 6]]   # 二维列表 = 一张表格
print(matrix[1][2])          # 第 2 行第 3 列 → 6

# 元组:定义后不能改(适合“固定的一组值”,如经纬度)
point = (116.4, 39.9)
try:
    point[0] = 0
except TypeError as e:
    print("报错:", e)
运行输出Python 运行结果
运行结果: ['苹果', '西瓜', '香蕉', '橙子'] pop 出: 橙子 ,剩下: ['苹果', '西瓜', '香蕉'] 6 报错: 'tuple' object does not support item assignment

字典与集合

先讲为什么列表靠“位置”找数据(第几个),但现实里我们更多靠“名字”找数据:用学号查成绩、用城市查天气。字典 dict 就是“键→值”的映射,查起来又快又直观。集合 set 则用来“去重”和“判断有没有”。
dict.pypython可运行
grade = {"张三": 90, "李四": 85, "王五": 77}
print(grade["张三"])     # 按键取值 → 90
grade["赵六"] = 95      # 新增一个
print("李四" in grade)  # 判断键是否存在 → True

# 集合:自动去重(集合“无序”,打印顺序不固定,故用 sorted 排好再看)
tags = set(["Python", "Python", "数据", "数据", "自动化"])
print(sorted(tags))     # ['Python', '数据', '自动化']
运行输出Python 运行结果
运行结果: 90 True ['Python', '数据', '自动化']
讲透字典像一本“活页词典”:grade["张三"] 比“在列表里找第几个”语义清晰得多。我们后面读 CSV 成绩表时,每行本质就是一个字典(列名 → 该格的值)。
dict2.pypython可运行
grade = {"张三": 90, "李四": 85, "王五": 77}
for name, g in grade.items():    # 同时拿到“键”和“值”
    print(name, "的分数是", g)

# 嵌套字典:一个学生有多门成绩
scores = {"张三": {"数学": 90, "英语": 88}, "李四": {"数学": 85, "英语": 92}}
print(scores["张三"]["数学"])     # 90

# 集合运算:共同好友 / 全部好友
a = {"小明", "小红", "小刚"}
b = {"小红", "小刚", "小强"}
print("共同好友:", sorted(a & b))   # 交集(集合无序,sorted 排好序看)
print("所有好友:", sorted(a | b))   # 并集
运行输出Python 运行结果
运行结果: 张三 的分数是 90 李四 的分数是 85 王五 的分数是 77 90 共同好友: ['小刚', '小红'] 所有好友: ['小刚', '小强', '小明', '小红']

条件判断:让程序会“做选择”

if.pypython可运行
age = 17
if age >= 18:
    print("已成年")
elif age >= 12:
    print("青少年")
else:
    print("儿童")

# 逻辑组合
score = 85
if score >= 60 and score < 90:
    print("及格,继续加油")
运行输出Python 运行结果
运行结果: 青少年 及格,继续加油
讲透
  • 冒号 + 缩进是 Python 的灵魂:哪个代码块属于 if,全靠缩进(通常 4 个空格)决定,不用写 {}。
  • elif = “否则如果”,else = “以上都不满足”。
  • and / or / not 把多个条件拼起来,这就是“逻辑运算”。
if2.pypython可运行
# 三元表达式:一行写完“如果…否则…”
age = 17
label = "成年" if age >= 18 else "未成年"
print(label)

# 成员判断 in:在不在里面
if "Python" in ["Python", "Java", "Go"]:
    print("会 Python 真好")

# 多档评级
score = 82
if score >= 90:   level = "优秀"
elif score >= 75: level = "良好"
elif score >= 60: level = "及格"
else:             level = "不及格"
print("等级:", level)
运行输出Python 运行结果
运行结果: 未成年 会 Python 真好 等级: 良好

循环:把重复的事交给电脑

loop.pypython可运行
fruits = ["苹果", "香蕉", "橙子"]
for f in fruits:              # 挨个取出
    print("我喜欢吃", f)

# 带编号地遍历
for i, f in enumerate(fruits):
    print(i, f)               # 0 苹果 / 1 香蕉 / 2 橙子

# 重复 N 次
for n in range(1, 4):         # 1,2,3
    print(n, "的平方是", n * n)
运行输出Python 运行结果
运行结果: 我喜欢吃 苹果 我喜欢吃 香蕉 我喜欢吃 橙子 0 苹果 1 香蕉 2 橙子 1 的平方是 1 2 的平方是 4 3 的平方是 9
讲透for ... in ... 是“遍历”结构:对序列里的每个元素执行一次。凡是“对一堆数据做同一件事”,第一时间就该想到循环。range(a, b) 生成从 a 到 b-1 的整数序列,是制造“次数”的常用手段。
loop2.pypython可运行
# while:条件满足就一直跑
n = 1
while n <= 3:
    print("第", n, "次")
    n += 1

# break 提前退出 / continue 跳过本次
for x in range(1, 6):
    if x % 2 == 0:
        continue          # 偶数跳过
    if x > 4:
        break             # 大于 4 就停
    print("奇数:", x)

# zip:同时遍历两个序列
names = ["张三", "李四"]
ages = [22, 25]
for name, age in zip(names, ages):
    print(name, "今年", age)
运行输出Python 运行结果
运行结果: 第 1 次 第 2 次 第 3 次 奇数: 1 奇数: 3 张三 今年 22 李四 今年 25

函数:把一段逻辑“封装”起来

函数 = 把一段逻辑装进「黑盒子」:喂进参数,吐出返回值实参(输入)avg([80, 92, 75])def avg(scores): return sum(scores) / len(scores)黑盒:内部怎么算,调用方不用管返回值(输出)82.33为什么封装:写一次、到处调;改一处、处处生效命名动词开头(calc_avg / send_mail);一个函数只做一件事;没有 return 就是返回 None默认参数 def f(x, n=2)——调用时可以不传;别用可变对象当默认值
先讲为什么当你发现“同一段计算要写三遍”,就该把它变成函数。函数让代码可复用、可测试、好读:你只管“喂入什么、得到什么”,不用管内部怎么算。
func.pypython可运行
def avg(numbers):            # 定义一个函数,numbers 是参数
    """计算一串数字的平均分"""
    return sum(numbers) / len(numbers)

data = [88, 92, 75, 100]
print("平均分:", avg(data))  # 调用函数

# 默认参数 & 任意参数
def greet(name, prefix="你好"):
    return f"{prefix},{name}"

print(greet("李华"))
print(greet("Tom", "Hello"))
运行输出Python 运行结果
运行结果: 平均分: 88.75 你好,李华 Hello,Tom
讲透
  • def 定义函数,return 把结果“交回来”;没有 return 的函数返回 None。
  • 函数里的 docstring(三引号注释)是给人和工具看的“说明书”,写清楚它干什么。
  • 默认参数让函数更灵活:不传就用预设值。
  • 把 avg 抽成函数后,换一批数据只要再调一次,逻辑零重复。
func2.pypython可运行
def greet(name, prefix="你好", times=1):
    return (f"{prefix},{name}!") * times

print(greet("李华"))              # 用默认 prefix / times
print(greet("Tom", "Hello", 2))   # 位置参数
print(greet("王芳", times=3))      # 关键字参数,顺序无所谓

# lambda:一行写的小函数,常配合 sorted / map
square = lambda x: x * x
print(square(5))                   # 25
nums = [{"age": 22}, {"age": 19}, {"age": 25}]
print(sorted(nums, key=lambda d: d["age"]))   # 按 age 从小到大
运行输出Python 运行结果
运行结果: 你好,李华! Hello,Tom!Hello,Tom! 你好,王芳!你好,王芳!你好,王芳! 25 [{'age': 19}, {'age': 22}, {'age': 25}]
避坑默认参数的值在函数“定义时”就固定了,且所有调用共享同一份。若默认值是列表这类可变对象,会被反复累加:def add(x, lst=[]): lst.append(x); return lst 连续调用会越加越多。正确写法:默认用 None,函数内再新建列表。

案例:学生成绩判定与统计

综合 列表 / 条件 / 循环 / 函数

把本章所有积木拼起来:给定一份成绩,逐人判定等级,并统计整体情况。

report.pypython可运行
def level(score):
    if score >= 90:  return "优秀"
    if score >= 75:  return "良好"
    if score >= 60:  return "及格"
    return "不及格"

records = [("张三", 92), ("李四", 80), ("王五", 55), ("赵六", 68)]
total = 0
for name, s in records:
    total += s
    print(f"{name}:{s} 分,等级 {level(s)}")

print("全班平均分:", total / len(records))
运行输出Python 运行结果
运行结果: 张三:92 分,等级 优秀 李四:80 分,等级 良好 王五:55 分,等级 不及格 赵六:68 分,等级 及格 全班平均分: 73.75
讲透注意 for name, s in records——列表里每个元素是个“二元组”,Python 可以直接拆包成两个变量。这个模式在数据处理里极常见:一行数据 = 一个元组,循环里拆开用。

第 2 章小结

动手练习

1用 f-string 输出“某某 的体重是 xx kg”,变量自己起名。

2列表 nums = [3, 1, 4, 1, 5, 9, 2, 6],用三行分别求它的长度、最大值、去重后的元素个数。

3用字典存三个城市的温度,再用循环打印“城市:温度”。

提示:第 2 题用 len()、max() 和 set();第 3 题用 for k, v in d.items()。先自己写,再点开参考。

练习参考.pypython可运行
name, weight = "小明", 60
print(f"{name} 的体重是 {weight} kg")

nums = [3, 1, 4, 1, 5, 9, 2, 6]
print("长度:", len(nums))
print("最大:", max(nums))
print("去重后个数:", len(set(nums)))

temp = {"北京": 26, "上海": 30, "广州": 33}
for city, t in temp.items():
    print(city, ":", t)
运行输出Python 运行结果
运行结果: 小明 的体重是 60 kg 长度: 8 最大: 9 去重后个数: 7 北京 : 26 上海 : 30 广州 : 33