Python:基础语法到底怎么学,才能从脚本初学者走到能独立写功能

Python 基础语法最容易学偏的地方,不是内容太难,而是学法太散。

常见顺序通常是这样的:

  • 今天学变量
  • 明天学 if
  • 后天学 for
  • 再过两天学函数

每一块单看都不难,但一旦让新手自己写一个稍微完整点的功能,代码往往会马上散掉。不是不会写单个语法点,而是不知道这些语法点应该怎么组合。

这一篇不按“概念词典”来讲,而是直接围绕一个实际小功能展开:做一个学生成绩统计脚本
用这个脚本把最基础、最常用、最容易写乱的几类语法串起来:

  1. 变量和基本类型怎么落到真实数据
  2. if / for / while 应该在什么场景下用
  3. 列表和字典为什么是脚本开发的高频核心
  4. 函数怎么把逻辑拆开,而不是把代码越写越长
  5. 输入、输出、异常处理怎么接进一个实际脚本

一、这篇文章要解决什么问题

读完这一篇,应该能独立完成下面这些动作:

  • 写一个接收输入的小脚本
  • 用列表和字典组织一组数据
  • 用分支和循环完成数据处理
  • 用函数拆开逻辑
  • 处理最常见的输入错误
  • 打印一份清晰的输出结果

如果这些动作都能自己做出来,Python 基础语法就不再只是“看过”,而是开始能支撑写实际功能。

二、先看最终要做出来的功能

先明确目标,不然语法学着学着又会散掉。

这篇文章要完成的功能是:

  • 输入多个学生姓名和分数
  • 计算平均分
  • 找出最高分和最低分
  • 标记不及格学生
  • 按分数从高到低输出结果

最终希望脚本输出类似这样:

1
2
3
4
5
6
7
8
9
10
11
共有 4 名学生
平均分: 80.25
最高分: Tom 95
最低分: Lucy 58
不及格学生: Lucy

成绩排名:
1. Tom - 95
2. Mike - 88
3. Rose - 80
4. Lucy - 58

这个需求不复杂,但已经足够把 Python 基础语法里最核心的几块连起来。

三、先从最小版本开始

先不要一上来就做输入和排序,先把最小版本跑起来。

新建 score_app.py

1
2
3
4
5
6
7
8
students = [
{"name": "Tom", "score": 95},
{"name": "Lucy", "score": 58},
{"name": "Mike", "score": 88},
{"name": "Rose", "score": 80},
]

print(students)

执行:

1
python score_app.py

输出:

1
[{'name': 'Tom', 'score': 95}, {'name': 'Lucy', 'score': 58}, {'name': 'Mike', 'score': 88}, {'name': 'Rose', 'score': 80}]

这个最小版本里已经出现了三类最基础的数据:

  • 列表 list
  • 字典 dict
  • 字符串和整数

在 Python 脚本里,这三类组合会高频出现。因为绝大多数实际脚本,本质上都在做一件事:拿到一组数据,做处理,再输出结果。

四、变量和基本类型,不要只背定义

1. 变量在脚本里就是“给数据起名字”

继续把代码拆开:

1
2
3
4
5
student_name = "Tom"
student_score = 95

print(student_name)
print(student_score)

输出:

1
2
Tom
95

这里不用背太多定义,先抓住一件事:变量的作用就是给后面的计算和判断提供可复用的名字。

2. 实际脚本里最常见的类型

这一类脚本最常用的基础类型通常是:

  • str:姓名、状态、命令参数
  • int:分数、次数、索引
  • float:平均分、比例、耗时
  • bool:是否通过、是否成功
  • None:当前没有值

可以直接验证:

1
2
3
4
5
6
7
8
9
10
11
name = "Tom"
score = 95
avg_score = 80.25
passed = True
comment = None

print(type(name))
print(type(score))
print(type(avg_score))
print(type(passed))
print(type(comment))

输出:

1
2
3
4
5
<class 'str'>
<class 'int'>
<class 'float'>
<class 'bool'>
<class 'NoneType'>

3. 一个实际错误

错误写法:

1
2
score = "95"
print(score + 5)

报错:

1
TypeError: can only concatenate str (not "int") to str

问题不在 Python 奇怪,而在于变量里存的是字符串 "95",不是整数 95

修复写法:

1
2
3
score = "95"
score = int(score)
print(score + 5)

输出:

1
100

这类问题在处理命令行输入、接口返回、文件内容时非常高频。基础类型不清楚,后面所有判断和计算都会乱。

五、列表和字典,为什么是脚本开发的核心

1. 为什么不用四五个独立变量

如果学生只有一个,用变量还能勉强写:

1
2
3
4
name1 = "Tom"
score1 = 95
name2 = "Lucy"
score2 = 58

但数据一多,这种写法马上失控。

所以实际脚本里更常见的做法是:

  • 用列表存“多个对象”
  • 用字典存“一个对象的多个字段”

例如:

1
2
3
4
students = [
{"name": "Tom", "score": 95},
{"name": "Lucy", "score": 58},
]

2. 怎么访问数据

1
2
3
print(students[0])
print(students[0]["name"])
print(students[1]["score"])

输出:

1
2
3
{'name': 'Tom', 'score': 95}
Tom
58

这就是 Python 脚本最常见的数据访问模式:

  • 列表用下标找元素
  • 字典用键找字段

3. 一个实际错误

错误写法:

1
print(students["name"])

报错:

1
TypeError: list indices must be integers or slices, not str

原因很直接:

  • students 是列表
  • 列表不能直接用字符串键取值

修复写法:

1
print(students[0]["name"])

六、if 分支到底在解决什么问题

分支的作用不是“语法题里必须有个 if”,而是在数据处理时做判断。

例如,找出不及格学生:

1
2
3
4
5
6
7
8
students = [
{"name": "Tom", "score": 95},
{"name": "Lucy", "score": 58},
]

for student in students:
if student["score"] < 60:
print(student["name"], "不及格")

输出:

1
Lucy 不及格

1. 实际里最常见的判断

基础脚本里,if 最常见的用途通常是:

  • 判断输入是否合法
  • 判断某个值是否为空
  • 判断某个状态是否达标
  • 根据不同条件走不同分支

2. 一个实际错误

错误写法:

1
2
3
4
5
6
score = 0

if score:
print("有分数")
else:
print("没有分数")

输出:

1
没有分数

这里不是程序错了,而是 0 在布尔上下文里会被当成假值。

如果想表达“是否为空”,写法应该更明确:

1
2
3
4
5
6
score = 0

if score is not None:
print("有分数")
else:
print("没有分数")

输出:

1
有分数

新手写条件判断时,最常见的问题不是不会写 if,而是判断条件表达得不准确。

七、forwhile 怎么选

1. 处理一组现成数据,用 for

例如遍历学生列表:

1
2
for student in students:
print(student["name"], student["score"])

输出:

1
2
3
4
Tom 95
Lucy 58
Mike 88
Rose 80

这种场景非常典型:已经有一组数据,只是要逐个处理,优先用 for

2. 不确定要循环多少次,用 while

例如持续输入学生数据,直到用户输入 q

1
2
3
4
5
6
7
8
9
10
students = []

while True:
name = input("请输入学生姓名,输入 q 结束: ").strip()
if name.lower() == "q":
break

score_text = input("请输入分数: ").strip()
score = int(score_text)
students.append({"name": name, "score": score})

这里循环次数不是预先写死的,所以 while 更合适。

3. 一个实际错误

错误写法:

1
2
3
4
index = 0

while index < len(students):
print(students[index]["name"])

这个循环会一直卡住,因为 index 从来没有增长。

修复写法:

1
2
3
4
5
index = 0

while index < len(students):
print(students[index]["name"])
index += 1

如果只是遍历已有列表,这里其实更适合直接写成:

1
2
for student in students:
print(student["name"])

八、函数不是为了高级,而是为了拆逻辑

如果所有逻辑都堆在一个文件顶部,很快就会长成这样:

  • 读取输入写在一起
  • 统计逻辑写在一起
  • 输出逻辑写在一起
  • 排错时不知道该改哪块

所以实际脚本一旦超过二三十行,就应该开始拆函数。

1. 先拆一个最简单的函数

1
2
3
4
5
6
def is_pass(score):
return score >= 60


print(is_pass(95))
print(is_pass(58))

输出:

1
2
True
False

2. 再拆统计函数

1
2
3
4
5
def calc_average(students):
total = 0
for student in students:
total += student["score"]
return total / len(students)

调用:

1
print(calc_average(students))

输出:

1
80.25

3. 一个实际错误

错误写法:

1
2
3
4
5
6
7
8
def calc_average(students):
total = 0
for student in students:
total += student["score"]
return total / len(students)


print(calc_average([]))

报错:

1
ZeroDivisionError: division by zero

修复写法:

1
2
3
4
5
6
7
8
def calc_average(students):
if not students:
return 0

total = 0
for student in students:
total += student["score"]
return total / len(students)

函数的价值不只是“代码更整齐”,还在于它会逼着你处理边界条件。

九、把语法点真正串起来

现在把前面的变量、列表、字典、分支、循环、函数合到一起。

score_app.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
def calc_average(students):
if not students:
return 0

total = 0
for student in students:
total += student["score"]
return total / len(students)


def find_failed_students(students):
failed = []
for student in students:
if student["score"] < 60:
failed.append(student["name"])
return failed


def print_report(students):
avg_score = calc_average(students)
failed_students = find_failed_students(students)

print(f"共有 {len(students)} 名学生")
print(f"平均分: {avg_score:.2f}")

for name in failed_students:
print(f"不及格学生: {name}")


students = [
{"name": "Tom", "score": 95},
{"name": "Lucy", "score": 58},
{"name": "Mike", "score": 88},
{"name": "Rose", "score": 80},
]

print_report(students)

执行:

1
python score_app.py

输出:

1
2
3
共有 4 名学生
平均分: 80.25
不及格学生: Lucy

这一步很重要,因为它说明基础语法真正有用了:

  • 变量负责存数据
  • 列表和字典负责组织数据
  • if 负责判断
  • for 负责遍历
  • 函数负责拆职责

十、加上输入,让脚本真的可用

如果数据永远写死在代码里,脚本就还是练习状态。再往前走一步,把输入接进来。

1
2
3
4
5
6
7
8
9
10
11
12
13
def input_students():
students = []

while True:
name = input("请输入学生姓名,输入 q 结束: ").strip()
if name.lower() == "q":
break

score_text = input("请输入分数: ").strip()
score = int(score_text)
students.append({"name": name, "score": score})

return students

调用:

1
2
students = input_students()
print_report(students)

实际输入输出可能是:

1
2
3
4
5
6
7
8
请输入学生姓名,输入 q 结束: Tom
请输入分数: 95
请输入学生姓名,输入 q 结束: Lucy
请输入分数: 58
请输入学生姓名,输入 q 结束: q
共有 2 名学生
平均分: 76.50
不及格学生: Lucy

一个实际错误

如果用户输入:

1
请输入分数: abc

代码会报错:

1
ValueError: invalid literal for int() with base 10: 'abc'

这就进入了基础脚本开发里非常重要的一层:输入校验

十一、异常处理怎么接进基础脚本

把输入处理得更完整一点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def input_score():
while True:
score_text = input("请输入分数: ").strip()
try:
score = int(score_text)
except ValueError:
print("分数必须是整数,请重新输入")
continue

if score < 0 or score > 100:
print("分数必须在 0 到 100 之间")
continue

return score

再把它接回主流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def input_students():
students = []

while True:
name = input("请输入学生姓名,输入 q 结束: ").strip()
if name.lower() == "q":
break

if not name:
print("姓名不能为空")
continue

score = input_score()
students.append({"name": name, "score": score})

return students

现在这个脚本才真正开始像一个可以交给别人使用的小工具。

十二、排序、统计和输出,怎么把基础语法再往前推一步

继续加一个按分数排序的输出。

1
2
3
4
5
6
7
8
9
10
def print_rank(students):
sorted_students = sorted(
students,
key=lambda item: item["score"],
reverse=True
)

print("\n成绩排名:")
for index, student in enumerate(sorted_students, start=1):
print(f"{index}. {student['name']} - {student['score']}")

调用后输出可能是:

1
2
3
4
5
成绩排名:
1. Tom - 95
2. Mike - 88
3. Rose - 80
4. Lucy - 58

这里虽然多了 sortedlambdaenumerate,但核心还是基础语法的延伸:

  • 处理列表
  • 访问字典
  • 遍历结果
  • 格式化输出

十三、完整版本放在一起

下面给出一个可以直接运行的完整版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
def calc_average(students):
if not students:
return 0

total = 0
for student in students:
total += student["score"]
return total / len(students)


def find_failed_students(students):
failed = []
for student in students:
if student["score"] < 60:
failed.append(student["name"])
return failed


def input_score():
while True:
score_text = input("请输入分数: ").strip()
try:
score = int(score_text)
except ValueError:
print("分数必须是整数,请重新输入")
continue

if score < 0 or score > 100:
print("分数必须在 0 到 100 之间")
continue

return score


def input_students():
students = []

while True:
name = input("请输入学生姓名,输入 q 结束: ").strip()
if name.lower() == "q":
break

if not name:
print("姓名不能为空")
continue

score = input_score()
students.append({"name": name, "score": score})

return students


def print_rank(students):
sorted_students = sorted(
students,
key=lambda item: item["score"],
reverse=True
)

print("\n成绩排名:")
for index, student in enumerate(sorted_students, start=1):
print(f"{index}. {student['name']} - {student['score']}")


def print_report(students):
avg_score = calc_average(students)
failed_students = find_failed_students(students)

print(f"\n共有 {len(students)} 名学生")
print(f"平均分: {avg_score:.2f}")

if failed_students:
print("不及格学生: " + ", ".join(failed_students))
else:
print("不及格学生: 无")

print_rank(students)


def main():
students = input_students()
print_report(students)


if __name__ == "__main__":
main()

十四、怎么测试这篇里的基础语法是不是真的掌握了

这类基础文章不能只看懂,要自己改过。

可以直接做这几个动作:

  1. 把及格线从 60 改成 70
  2. 增加一个“优秀学生”统计,条件是 score >= 90
  3. 增加一个字段 class_name
  4. 只输出某个班级的学生
  5. 把平均分保留两位小数

如果这些改动都能独立完成,说明不是只会照抄代码,而是已经开始会组合这些基础语法。

十五、一个实际排错场景

这个脚本最常见的实际问题通常不是 Python 本身有多难,而是数据结构一改,代码某一处忘了同步。

例如原来学生数据是:

1
{"name": "Tom", "score": 95}

后来有人改成:

1
{"student_name": "Tom", "score": 95}

print_rank() 里还是写:

1
student["name"]

这时会报错:

1
KeyError: 'name'

排查顺序应该很直接:

  1. 先看报错是哪一行
  2. 再看这一行取的是哪个键
  3. 再回头看实际数据结构
  4. 最后统一字段名

这种问题在脚本开发里非常常见。基础语法学完以后,真正影响效率的往往不是语法记不住,而是数据结构和代码逻辑没有保持一致。

十六、一个实际练习

可以直接把这一篇变成一个完整练习。

练习目标:做一个“商品库存统计脚本”。

要求:

  1. 每个商品至少包含 namecountprice
  2. 输入多个商品数据
  3. 统计总库存数量
  4. 统计总库存金额
  5. 输出库存不足的商品,例如 count < 5
  6. 按库存金额从高到低排序输出

如果这个练习能独立做完,说明这一篇最核心的几类基础语法已经开始真正会用了。

十七、这篇文章学完以后,下一步应该补什么

如果这一篇已经能跟着做完,下一步最适合继续补的是:

  1. 列表、元组、字典、集合为什么不只是“会用”
  2. 函数参数、可变对象、作用域为什么总让新手犯错
  3. 文件处理和异常处理在脚本里怎么继续往前接

因为到这一步,基础语法已经能支撑写小功能了。接下来真正会频繁卡住的,是数据结构理解不够深,以及函数和对象边界开始混乱。

十八、结语

Python 基础语法最好不要按孤立的定义去学,而应该放进一个实际功能里反复组合。

这一篇真正要掌握的,不是把 ifforlistdict 这些词背下来,而是知道:

  • 什么数据适合放进列表
  • 什么字段适合放进字典
  • 什么判断该放进 if
  • 什么逻辑该拆成函数
  • 什么输入必须做校验

只要这些组合关系开始清楚,Python 基础语法就不再只是“看过”,而是已经能支撑写出第一批真正可用的小功能了。