打卡Python王者归来第5天
今天是我的Python学习打卡第5天。老实说,前4天走得有点跌跌撞撞,从完全接触编程到能写出简单的条件判断和循环,中间无数次想放弃又捡起来。但真正让我感觉到"入门了"的,恰恰是这第5天——因为我开始理解函数和数据结构这两个概念,恰好是编程里最核心、也最值得花时间啃的骨头。
如果你也在学Python,或者正卡在某个阶段不知道该往哪使劲,这篇第5天的打卡记录也许能给到你一些方向。我会把这一天的学习内容拆得很细:学了什么、为什么这么学、怎么练最有效,以及我踩过的坑。不是给你灌鸡汤,而是真实复盘这一天的得与失。
1. 第5天在整条学习路线中的定位
1.1 为什么前4天那么“碎”
前4天我干了什么?无非是:第1天装环境、跑通"Hello World";第2天认识变量和基本数据类型;第3天写if条件判断;第4天折腾for和while循环。看起来零散,但这些其实是Python的砖块。没有这几天的底子,今天的内容根本接不住。
到了第5天,学习重心从"单条语句能干什么"上升到了"怎么把语句组织起来复用、怎么在内存里批量管理数据"。如果说前4天是在认识单个汉字,第5天就是开始学组词造句。函数解决的是"动作的封装",列表和字典解决的是"数据的收纳"。这两个东西一旦掌握了,基本上就能写出有点逻辑的程序了,不再是纯粹一行行执行。
我个人的感受是,第5天是一个分水岭。能不能坚持下去,往往取决于这一天之后你有没有一种"我好像能写点小工具了"的感觉。因为函数和数据结构的学习成果非常看得见:写一个函数,调用它,输出结果;建一个列表,循环处理里面的每个元素——这种反馈比枯燥的语法练习强太多。
1.2 这一天到底该达成什么目标
学习最忌讳漫无目的。我在开始第5天之前,给自己定了三个必须达成的目标:
第一,能独立写一个带参数和返回值的函数,并且理解参数怎么传、返回值怎么接。不是照着抄,而是能自己设计一个小功能把它封装成函数。
第二,弄懂列表和字典的增删改查,知道在什么场景下用列表、什么场景下用字典。这一步特别关键,因为很多人学完语法但写程序时不知道选哪个容器,导致代码又臭又长。
第三,通过做一个综合小练习,把函数和数据结构串起来用。这也是检验前面学的if和循环是不是真的掌握了的好机会。
定目标是必要的,否则一天学下来,看似看了很多资料,实际上脑子里还是一团浆糊。我在前几天的打卡里吃过这个亏——视频跟着看完了,语法跟着敲完了,关上电脑什么都写不出来。
2. 函数:从抄代码到写代码的关键一步
2.1 先理解函数是干嘛的
大多数教程上来就讲函数定义、参数、返回值,初学者容易陷入语法细节里出不来。我的理解方式是先想一个问题:为什么需要函数?
比如我要计算一个长方形的面积。一次两次,直接写width * height就行了。但如果我在程序里20个地方都要算面积呢?每个地方都写一遍?那不仅累,而且万一以后面积公式要加上什么系数,你还得一个一个去改。函数就是把这一小块逻辑装进一个"盒子"里,给它起个名字,需要的时候喊它一声。
这个类比特别适合初学者理解:函数像一台果汁机。你把水果放进去(参数),按键启动(调用),出来的是果汁(返回值)。不用关心果汁机内部怎么运转的,你只要知道输入什么、输出什么、怎么触发就行。
了解了意义再去看语法,就顺多了。Python里定义一个函数用def关键字,后面跟函数名、括号和冒号。函数体要缩进,最后用return把结果送出来。比如:
def calculate_area(width, height): area = width * height return area这个函数接收两个参数,计算面积后返回结果。调用的时候:result = calculate_area(5, 3),得到15。
2.2 参数传递里的那些坑
说实话,参数这部分我前两次打卡都没彻底搞明白,今天是真懂了。核心要分清"形参"和"实参"。
形参是定义函数时写在括号里的变量名,比如上面例子里的width和height;实参是真正调用时传进去的值,比如5和3。函数在运行时,把实参的值绑定到形参上,然后执行函数体。这个关系理清了,很多报错就能看懂了。
还有一个常见知识点是位置参数和关键字参数。位置参数就是按顺序传参,第一个值给第一个形参,第二个给第二个。关键字参数是调用时指名道姓地传:calculate_area(width=5, height=3),这样即使顺序反了也没关系。更灵活的是可以在函数定义时设置默认值:
def greet(name, greeting="Hello"): return f"{greeting}, {name}!"如果调用greet("小明"),输出"Hello, 小明!";如果调用greet("小明", "Hi"),则输出"Hi, 小明!"。这个特性特别实用,尤其是函数有很多可选配置的时候。
不过要注意,带默认值的参数要放在没有默认值的参数后面,否则会报语法错误。这是Python的规定,原因是为了避免调用时的歧义。
2.3 返回值不是必须的,但设计好很重要
不少初学者以为函数必须写return。其实不是,函数完全可以没有返回值。比如我只想打印一段信息,不需要拿结果做什么,那就不需要return。但这种函数执行完会返回None,这也是一个很容易让人困惑的点。
def show_info(name): print(f"当前用户是:{name}")调用它时打印正常,但如果你写result = show_info("张三"),然后打印result,会看到None。这是正常的,不需要慌。
更值得留心的是return的另一个作用:一旦执行到return,函数就结束了,后面的代码不会继续跑。所以如果有"提前返回"的逻辑,比如参数不合法就直接返回,可以用这个特性:
def safe_divide(a, b): if b == 0: return "除数不能为零" return a / b这样代码既简洁又安全。我当时学到这里,对"return既是返回值也是退出标记"这个双重身份印象特别深,因为之前总觉得函数只能有一种写法。
3. 数据结构:列表和字典的实战选择
3.1 列表:有序的“收纳盒”
列表是我觉得最贴近日常思维的容器。它就像一条有序的储物柜,每个格子都有自己的编号(下标),从0开始数。你可以往里面加东西、取东西、改东西、删东西,还能一口气遍历所有格子。
创建列表有两种常用方式:
fruits = ["苹果", "香蕉", "橙子"] numbers = list(range(1, 6))访问元素用下标:fruits[0]是"苹果"。修改:fruits[1] = "西瓜"。追加元素用append()方法,删除可以remove()按值删,也可以用pop()按索引删。
遍历列表推荐用for循环直接拿元素:
for fruit in fruits: print(fruit)这种方式最直观,不需要关心下标。如果确实需要下标,可以用enumerate():
for index, fruit in enumerate(fruits): print(index, fruit)3.2 字典:按照名字找东西
列表适合按顺序存放数据,但如果你要根据某个属性快速查找信息,字典更合适。字典是键值对的集合,像一本通讯录——你输入一个名字(键),立刻就能得到电话号码(值)。
创建字典:
student = { "name": "小明", "age": 18, "city": "上海" }取值:student["name"]得到"小明"。修改:student["age"] = 19。新增键值对:student["score"] = 90。删除:del student["city"]。
有一点值得提醒:从字典里取一个不存在的键会直接报KeyError。所以更安全的做法是用get()方法:
score = student.get("score", 0)如果键不存在,返回默认值0,而不是报错。这在处理不确定数据时非常实用。
3.3 什么时候用列表,什么时候用字典
这是新手最常纠结的问题。我的判断标准很简单:如果数据是有顺序的一串同类事物,用列表;如果需要根据某个标识快速找到对应信息,用字典。
比如记录一周每天的体温,就用列表,因为顺序有意义;但要记录每个学生的成绩,用字典更好,因为你是通过学生姓名查成绩,而不是一个个翻列表。
列表和字典还能嵌套使用。比如一个列表里装多个字典:
students = [ {"name": "小明", "score": 88}, {"name": "小红", "score": 95}, {"name": "小刚", "score": 76} ]然后配合循环,就能批量处理数据。这一招在很多实战项目里是标配,学会了基本就能应对大部分数据组织的场景了。
4. 实操练习:把函数和数据结构串起来
4.1 设计一个练习:学生成绩管理小工具
学完知识点不等于会用了,所以我给自己安排了一个综合练习。目标是写一个简单的学生成绩管理工具,支持三个功能:录入成绩、查看平均分、查看最高分和最低分。
这个练习的好处在于,它把第5天学的函数和列表字典全用上了,同时还复习了循环和条件判断。综合训练效果比做一堆碎片化的选择题强得多。
先定数据结构:用一个列表students存储所有学生信息,每个学生是一个字典,包含姓名和成绩。
students = [] def add_student(name, score): student = {"name": name, "score": score} students.append(student) print(f"已录入 {name} 的成绩:{score}")添加函数很简单,关键是调用几次以后,students列表里就攒了好几个字典。
然后写统计函数:
def calculate_stats(): if len(students) == 0: print("暂无数据,请先录入成绩") return scores = [s["score"] for s in students] average = sum(scores) / len(scores) highest = max(scores) lowest = min(scores) print(f"平均分:{average:.2f}") print(f"最高分:{highest}") print(f"最低分:{lowest}")这里用了一个列表推导式s["score"] for s in students,这是Python里很常见的写法——从列表里的每个字典中取出score值,生成一个新列表。当时我刚看到这个语法时觉得有点绕,但练了两遍就顺手了,因为它其实就是在说"对students里的每个人,把他的分数拿出来"。
4.2 让程序“活”起来:加入交互循环
静态的数据录入没什么意思,更接近真实场景的是一个可以反复操作的命令行菜单。所以我加了一个while循环,让用户选择做什么:
while True: print("\n1. 录入成绩") print("2. 查看统计") print("3. 退出") choice = input("请选择操作:") if choice == "1": name = input("输入姓名:") score = float(input("输入成绩:")) add_student(name, score) elif choice == "2": calculate_stats() elif choice == "3": print("已退出,再见!") break else: print("无效选项,请重新输入")这个循环把这个小工具变成了一个"能跑的系统"。虽然还很简陋,但用户真的可以在命令行里录入多个学生、查看统计结果,然后退出。写完之后我第一次有了一种"我会编程了"的感觉,不是说大话,而是这种即时反馈确实很能增强信心。
做完这个练习,我建议你也模仿着做,但不要直接抄代码。把功能需求自己理一遍,数据结构自己定,函数自己写,哪怕慢一点也值得。编程能力是写出来的,不是看出来的。
5. 常见问题与排错心得
5.1 缩进错误是最“容易”犯的错
Python对缩进要求极其严格。一个IndentationError: expected an indented block就能让新手抓狂半天。我的经验是:函数体、循环体、条件体里的代码统一用4个空格缩进,不要混用Tab和空格。编辑器最好设置为"Tab自动转4空格",这样省去很多麻烦。
另外,空函数如果还没想好怎么写,可以用pass占位,否则会因为"函数体不能为空"报错:
def future_func(): pass5.2 变量作用域引发的奇怪现象
我第5天遇到一个很典型的问题:函数内部修改了变量,函数外面打印却还是老样子。后来才明白这是"局部变量"和"全局变量"的区别。
简单说,函数内部赋值的变量默认是局部变量,函数执行完就被销毁了,不影响外面的同名变量。如果确实需要在函数里修改全局变量,需要用global声明——但我的建议是,尽量少用global,因为会让代码难以追踪。更好的办法是让函数通过参数接收数据,再通过返回值把结果"带出来"。这样数据流向清晰,代码更好维护。
我在练习里的add_student函数就是例子:它通过append()修改了外面的students列表,但没有重新赋值,所以不需要global也能生效。这里有一个微妙但很重要的区别:修改对象本身不需要global,重新绑定变量名才需要。
5.3 类型错误:浮点数与字符串混用
录入成绩的时候我一开始用input()直接接收,然后存进字典。后来算平均分的时候发现sum(scores)报错。原因很简单:input()返回的是字符串,比如"88",而计算平均值需要数字类型。
解决办法是前面代码里写的:score = float(input("输入成绩:")),把字符串转成浮点数再存。这个坑非常典型,几乎每个初学者都会踩。记住一个原则:从input()拿到的永远是字符串,需要数值计算必须先转换。
5.4 调试技巧:不要急着改代码,先打印
我学到一个特别有用的调试思路:程序报错了,或者结果不对,不要凭感觉乱改。先在关键位置加上print(),把中间过程打出来看看。
比如算平均分之前,我先打印一下scores是什么,是不是预期的[88, 95, 76]这样的列表。如果列表不对,再往前查,找到是录入环节出了问题还是取数环节出了问题。这种"变量可视化"的调试方法,比盯着代码发呆高效太多了。
等确认逻辑正确后,再把这些调试用的print()删掉,保持代码干净。这一步我每次都会做,算是一点点职业习惯。
6. 第5天打卡给我带来的三个收获
学完这一天,我最大的体会是:Python的学习曲线其实是先缓后陡再缓。前4天是缓坡,每天学点貌似简单的东西;第5天突然变陡,因为函数和数据结构把前面的知识真正串联起来了。但只要咬牙翻过这个陡坡,视野一下子就开阔了。
第二个收获是,我现在敢于自己"造轮子"了。虽然是很简陋的小工具,但那种从零构思一个功能、自己拆解、自己实现的过程,才是编程真正的乐趣所在。抄一百段代码,不如自己写一个能跑的小程序。
第三个收获是,我越来越明白"学习编程的唯一方式就是编程"这句话了。看视频、翻教程都只是输入,只有动手写才形成输出循环。第5天我花在写代码和排错上的时间,比看资料的时间多得多,效果确实验证了这一点。
如果你也正在学习Python的第5天、第6天甚至更晚的阶段,我想说的是:别急着往前赶,把函数和数据结构这些地基打牢。后面学的文件操作、类、第三方库,全都建立在这些核心概念之上。地基松了,越往上盖越心虚。
明天我会继续打卡第6天,计划学文件读写和异常处理。到时候如果遇到有意思的坑,再回来跟你分享。这次就到这里,我要去把今天的练习再重构一遍了——因为我又想到了一个更好的数据组织方式。