今天是我 python 入门第 5 天,前四天差点把我劝退——不是看不懂代码,而是不知道学这些东西到底能干嘛。print() 会了,变量会了,if 会了,但一合上教程,脑子里还是空的。直到第 5 天,我试着把变量、列表、函数和文件读写串起来,做了一个超简单的文本统计器,才真正有了“我会编程”的感觉。如果你也正学到第 5 天,或者刚接触 Python 四五天、正在犹豫要不要继续,这篇内容就是写给你的。
我会把第 5 天的学习内容拆开讲,包括变量和类型转换、列表切片、函数定义,以及如何用这些知识完成一个能跑通的小项目。前四天你已经装好了 Python、写过几个 print 和 if,那今天就往“组合逻辑”的方向走一步。放心,不需要任何天赋,只要愿意跟着敲,天黑前你也能跑出第一个属于自己的小工具。
1. 第 5 天学什么:学习路线与思维转变
1.1 为什么第 5 天是个分水岭
很多人学 Python 死在第四五天,不是因为内容突然变难,而是因为前几天的知识都是“孤立的点”。第 1 天装环境,第 2 天学 print 和变量,第 3 天学 if 和 while,第 4 天学 for 和列表,到了第 5 天,如果还继续一个知识点一个知识点地往下看,你很快就会陷入“看懂了但不会写”的状态。
第 5 天的正确打开方式,是把前面学过的变量、类型、列表、循环、条件判断这些点,用一个新的语法结构“函数”串起来。就像你手里有了一堆积木,之前只是把它们挨个摆出来看,今天才是第一次拼成一个小房子。
所以第 5 天不要贪多,更不要跑去啃什么高阶内容。我给自己定的任务只有三件:彻底搞懂变量的本质和类型转换,熟练使用列表和切片,开始用 def 封装代码。如果能再来一个小项目收尾,那这一天的学习效率会非常高。
1.2 我的一天时间安排:少而精才能真学会
第 5 天我给自己安排的时间是上午一小时、下午一小时、晚上一小时,中间穿插动手练习,绝不一天刷十节课。
上午只解决“变量和类型转换”。因为 input() 在 Python 里返回的是字符串,而你要拿它做数字运算时,总会碰到“转 int 却报错”之类的问题。把这一块搞透,后面写任何交互程序都不卡壳。
下午只看“列表和切片”。列表是 Python 里最常用的容器,切片更是省事神器。我见过很多人学了半年还是背不住 list[::-1] 的作用,其实就是因为当时没搞懂三段的边界规则。
晚上开始写函数,再做一个文本统计的小项目。这个小项目会逼着你把上午和下午的知识全用一遍,用了才知道自己哪里没懂。
你可以根据自己作息调整时间,但核心原则不变:宁可少学两个新语法,也要把学过的语法练到手熟。第 5 天不是比谁看的多,而是比谁能在不看教程的情况下,独立写出一个小程序。
1.3 从“抄代码”到“拆代码”的习惯转换
前四天你可能都是照着教程一行行敲,这很正常。但第 5 天开始,我强烈建议你做一件看起来很“破坏”的事:把别人的代码先运行成功,然后故意改坏它。
比如教程里写了for i in range(5):,你就改成for i in range(5, 0, -1):看看会发生什么;函数里明明有 return,你删掉 return 再打印一下调用结果;列表切片本来是a[1:3],你改成a[3:1]看看结果是不是空。
这种玩法的价值在于,报错信息会成为你的老师。新手普遍怕报错,一看到红字就慌,但 Python 的报错其实写得很清楚,它会告诉你在哪个文件、哪一行、发生了什么错误。你故意把代码弄坏,就能在安全的状态下提前熟悉各种报错,真正写代码时遇到它们就不会慌。
从第 5 天起,把心态从“复读机”切换到“实验员”。遇到不懂的就去改、去试、去观察,这比任何教程都管用。
2. Python 变量进阶:标签不是盒子,类型转换别踩坑
2.1 用 id() 看清变量和对象的关系
很多教程告诉你“变量就像盒子,里面装了值”,这句话对初学者友好,但到了第 5 天,你会发现它可能会误导你。
真正的理解是:Python 变量更像一个贴在对象上的标签。你用a = [1, 2, 3]时,并不是把 [1,2,3] 这个“盒子”放进变量 a 里,而是把变量名 a 指向了内存中那个列表对象。如果再加上一句b = a,那 b 和 a 指向的是同一个列表对象。
试试下面这段代码:
a = [1, 2, 3] b = a b.append(4) print(a) # [1, 2, 3, 4] print(b) # [1, 2, 3, 4] print(id(a), id(b)) # 两个值相同很多人会认为 a 没有变,实际上 a 也跟着变了。原因就是 a 和 b 只是同一个列表的两个标签。想复制一份独立的列表,要用切片或者copy():
b = a[:] b.append(5) print(a) # [1, 2, 3, 4] a 不变可以这样理解:a 是某个文件在桌面上的快捷方式,b 是另一个快捷方式,两个快捷方式指向同一个文件。你修改文件内容,不管从哪个快捷方式打开,内容都会变。想复制文件本身,必须重新创建一份。
判断两个变量是否指向同一个对象,用id()或is,而不是==。==只比较值是否相等,is才比较身份是否相同。这个知识点第 5 天能理解到“清楚”程度就够了,后面学函数参数传递时还会再遇到。
2.2 input() 返回字符串,数字计算前记得转类型
第 5 天最常见的报错之一是TypeError: can only concatenate str (not "int") to str。出现这个错,十有八九是你忘了处理 input() 的返回类型。
官方文档写得很明白,input() 接收用户输入时,返回的一定是字符串。哪怕用户输入的是“18”,你在代码里拿到的也是字符串"18",不是整数 18。
所以当你写“明年年龄”这种程序时,必须先转类型:
age = input("请输入你的年龄:") print(type(age)) # <class 'str'> age = int(age) next_year_age = age + 1 print("明年你", next_year_age, "岁")这里如果用age + 1直接计算,Python 并不知道该怎么把字符串和整数相加,所以直接抛 TypeError。解决办法就是在计算前手动转成 int。
同理,"5" + "3"你会得到"53",这是个字符串拼接,不是整数加法。Python 不会因为你看到 5 和 3 长得像数字,就自动帮你做加法。这是很多新手第 5 天容易懵的地方,实际跑一遍就明白了。
2.3 类型转换的四个隐藏陷阱
除了一头一尾的字符串和整数互转,Python 的类型转换里还有几个特别容易坑人的点,我单独拿出来讲。
第一个是int(3.9)。很多人以为它会四舍五入成 4,其实结果永远是 3,它只会把小数部分直接砍掉。想四舍五入要用round(3.9)。
第二个是int("3.9")。如果你想把字符串 “3.9” 变成整数,直接 int() 会抛ValueError。正确做法是先转成浮点数,再转成整数:int(float("3.9"))。
第三个是bool("False")。这是一个经典误解,因为字符串"False"非空,所以转成布尔值时是 True。在 Python 里,只有一个空字符串""会变成 False,其他非空字符串都是 True。同样地,bool([0])是 True,因为列表里有一个元素,而空列表bool([])才是 False。
第四个是True + 1。布尔类型其实是整数类型的子类,True 是 1,False 是 0。所以在做统计或者遇到奇怪的算术结果时,你要想到这个特性。
我把这些整理成了一张速查表:
| 表达式 | 结果 | 原因 |
|---|---|---|
int(10.9) | 10 | 直接截断小数,不四舍五入 |
int(10.9)vsround(10.9) | 10 vs 11 | 想要四舍五入请用 round |
int(float("3.9")) | 3 | 先转浮点才能再转 int |
bool("False") | True | 非空字符串都是 True |
bool([]) | False | 空列表是 False |
True + 1 | 2 | bool 是 int 的子类 |
看到这些,你可能会觉得 Python 有点“不讲武德”,但这些特性都有历史原因和设计逻辑。第 5 天只需要记住,类型转换不一定按人的直觉走,动手验证永远比猜靠谱。
2.4 自测清单:第 5 天能不能过关
我给自己出过一套“类型转换自测题”,每次都像在做小游戏。你也能试试,先预判结果,然后运行代码验证:
print(int(10.5)) print(float("4.2")) print(str(123) + "4") print(bool("")) print(bool("0")) print("5" + "3") print(5 + 3) print(int("12.9")) # 这句会报错,但有价值如果大多数结果你都能答对,说明类型转换这一关过了。如果答错,也别灰心,把报错信息和结果对照看一遍,比背十遍笔记都有效。
第 5 天开始,我建议你养成一个习惯:写代码时多用type()函数检查数据。比如print(type(变量)),跑一下看到底是str还是int还是list。别怕那行输出碍眼,它能帮你少走很多弯路。
3. 列表与切片:Python 最常用的“容器手感”
3.1 增删改查的五个日常方法
列表是你往后写爬虫、写数据分析、写自动化脚本时天天打交道的数据类型。第 5 天不需要记所有方法,但下面这几个必须形成肌肉记忆。
append()在列表末尾追加一个元素,这个最常用,比如收集用户输入时就靠它。
insert(index, item)在指定位置插入元素,比如列表原来有["a", "b"],你想把"x"插到第 1 个位置,就写lst.insert(1, "x")。
pop()删除并返回末尾元素;pop(index)删除指定位置的元素并返回它。它和remove()最大的区别是:pop 靠索引,remove 靠值。
remove(value)按值删除,而且只删除第一个匹配的元素。如果值不存在,会抛ValueError。
还有个del关键字,它不是方法,但也很常用:del lst[0]删除指定索引位置的元素,但不返回。
写一个简单例子感受一下:
shopping = ["牛奶", "面包"] shopping.append("鸡蛋") print(shopping) # ['牛奶', '面包', '鸡蛋'] shopping.insert(1, "苹果") print(shopping) # ['牛奶', '苹果', '面包', '鸡蛋'] item = shopping.pop() print(item) # 鸡蛋 print(shopping) # ['牛奶', '苹果', '面包'] shopping.remove("苹果") print(shopping) # ['牛奶', '面包']在实际写程序时,你要想清楚自己的需求:是“需要知道删除的是哪个元素”用 pop;是“只要列表里别再有这个值”用 remove;是“按位置暴力删除”用 del。我见过不少新手只知道 append,结果想删元素时卡半天,今天把其它几个也练熟,后面写代码会顺畅很多。
3.2 切片左闭右开:一次搞懂 start、stop、step
切片是 Python 最优雅的语法之一,也是很多新手第 5 天怎么都记不住的东西。其实它只要抓两个关键词:左闭右开、步长。
格式是lst[start:stop:step],start 是开始索引,stop 是结束索引,但 stop 对应的元素取不到。也就是说,实际取的是[start, stop)这个半开区间。
nums = [0, 1, 2, 3, 4, 5] print(nums[1:4]) # [1, 2, 3] print(nums[:3]) # [0, 1, 2] 开头省略 start,从 0 开始 print(nums[3:]) # [3, 4, 5] 结尾省略 stop,取到末尾 print(nums[::-1]) # [5, 4, 3, 2, 1, 0] print(nums[4:1:-1]) # [4, 3, 2] step 为负数时从右往左取为什么设计成左闭右开?因为这样计算区间长度非常方便:len(nums[1:4])就是4 - 1 = 3。而且两个连续区间[1,4)和[4,7)能无缝衔接,不会重叠也不会漏数据。
负索引也别怕:-1是最后一个,-2是倒数第二个。负索引和切片配合使用很好用,比如想取除第一个和最后一个之外的中间部分,可以直接写nums[1:-1]。
切片还有一个隐藏技能,就是它会返回一个新列表。因此想复制列表时,写new_lst = old_lst[:]是最简单的深拷贝方式。你可以回看前面变量那节,这就是解决“两个变量互相影响”的最直接办法。
我把常用切片整理成一张表,方便你贴在笔记里:
| 写法 | 结果 | 说明 |
|---|---|---|
lst[:] | 整个列表副本 | 常用于复制列表 |
lst[1:] | 去掉第一个元素的列表 | 相当于跳过头 |
lst[:-1] | 去掉最后一个元素的列表 | 尾部不要 |
lst[::-1] | 倒序列表 | 最优雅的反转方法 |
lst[::2] | 隔一个取一个 | 取偶数位元素 |
lst[1:5:2] | 从索引1到4,步长2 | 取[1,3] |
切片这东西,你只看永远觉得玄,自己把start、stop、step各改几次,跑一遍,很快就能形成直觉。
3.3 列表推导式:用一行代码完成筛选
第 5 天能在“看得懂”层面接触一下列表推导式就行,但我要说我自己的经历:当我第一次看懂列表推导式时,整个人都精神了,因为到这一步你才真正感受到 Python 的“简洁”不是吹的。
假设你想从一个 1 到 10 的列表里筛出所有偶数,用普通循环要写四五行,列表推导式一行就够了:
numbers = list(range(1, 11)) even_numbers = [x for x in numbers if x % 2 == 0] print(even_numbers) # [2, 4, 6, 8, 10]它的读法是:对 numbers 里的每一个 x,如果x % 2 == 0成立,就把 x 放进新列表里。本质就是一个 for 加一个 if,只是被压缩成了一行。
在实际项目里,筛选列表、清洗数据时这样写又快又清爽。比如在文件里读进很多行,想去掉空行,可以写:
lines = [line.strip() for line in lines if line.strip()]但第 5 天要切记一点:不要堆多重循环。新手阶段一重循环加一个条件就够用,列出所有数字的平方这类简单任务也可以用它:
squares = [x * x for x in range(1, 6)] print(squares) # [1, 4, 9, 16, 25]列表推导式的本质是“一次性构建新列表”,如果你想要的是逐行处理、过程复杂,那还是老老实实写 for 循环。代码的可读性比“看着很厉害”重要得多。
4. 函数与 def:让代码变成可以反复使用的积木
4.1 def 只是定义名字,调用时才会执行
前四天你可能已经写过“顺序执行”的代码,但到了第 5 天,你必须开始习惯用函数组织代码。否则越往后写,代码就越是挤成一坨,自己想改都找不到位置。
函数定义的语法非常简单:
def greet(name): return "你好," + name result = greet("小明") print(result) # 你好,小明很多新手的第一个困惑是:为什么def下面几行在我调用 greet 之前没有输出?因为 Python 执行到 def 时,只是把函数体存起来,并把函数名绑定到这段代码上,并不会真的去运行它。真正运行发生在你调用greet("小明")那一刻。
这也意味着,函数调用必须发生在定义之后。如果你颠倒顺序:
print(greet("小明")) # NameError: name 'greet' is not defined def greet(name): return "你好," + name运行时就会报错,因为执行到调用时,greet 还没被绑定到函数对象上。你写代码时最好先定义后使用。
函数参数分位置参数和关键字参数。位置参数是按顺序传:
def describe(name, age): return name + "今年" + str(age) + "岁" print(describe("小红", 16)) # 小红今年16岁 print(describe(age=16, name="小红")) # 关键字参数可以不按顺序现在你可能觉得这很基础,但第 5 天养成“把一段独立逻辑放进函数”的习惯,后面写项目时才会少吃苦。
4.2 return 和 print 的“糊涂账”
我认为“函数没有 return 却拿去用”是第 5 天最容易踩、也最让人难受的一个坑。很多人写了这样的代码:
def add(a, b): print(a + b) result = add(3, 5) print(result) # 第二行输出 None运行结果第一行是 8,第二行是 None。原因是 add 函数只把a+b打印了出来,并没有把计算结果“返回”给调用者。result 拿到的其实是函数默认的返回值 None。
你可以这样理解:print 是函数把结果喊出来给你看,return 是函数把结果写在纸条上递给你。只看不说话,你手里当然什么都没有。
想拿到计算结果,必须用 return:
def add(a, b): return a + b result = add(3, 5) print(result) # 8这里还有一个隐藏知识点:如果函数没有 return,它执行到最后一行也会默认返回 None。你可以在自己的代码里写return单独使用来提前结束函数:
def check(age): if age < 18: return "未成年" return "成年"检查return和print是否分清的标准就是:把函数返回的值交给另一个变量继续用。如果那个变量总是 None,就要回头看看自己是不是只写了一堆 print,忘了写 return。
4.3 默认参数用可变对象会出大乱子
最后讲一个你可能在第 5 天不太会遇到,但一旦遇到就特别难排查的坑:默认参数别用可变对象。
看这个例子:
def add_item(item, target=[]): target.append(item) return target print(add_item(1)) # [1] print(add_item(2)) # [1, 2] print(add_item(3)) # [1, 2, 3]第二行你应该期待得到[2],结果却是[1, 2]。原因在于,默认参数target=[]只在函数定义时创建一次,之后每次调用,如果没有传 target,都会复用这同一个列表。于是第一次调用往里面添了 1,第二次再添 2,列表就累积了。
正确的做法是,默认值用 None,在函数内部创建新列表:
def add_item(item, target=None): if target is None: target = [] target.append(item) return target这个坑实际在面试里、复杂项目里经常出现。第 5 天你只要知道“默认值如果写一个可变对象,会有共享问题”这件事就够了。你可以把这个案例抄下来,等后面学完可变对象拷贝再回头品味。
5. 小项目实战:用第 5 天所学写一个文本统计器
5.1 需求拆解与伪代码
今天的高潮项目,是写一个文本统计器。别觉得“项目”两个字离你很远,这个程序很单纯:读取一个纯英文文本文件,然后输出文本里有多少个字符、多少个单词,以及出现次数最多的 3 个单词。
我为什么强调英文?因为英文单词天然用空格分隔,用 split() 就能切出来。如果是中文,一句话连在一起,暂时还不适合新手处理。等你以后学了第三方库,再回来处理中文也不迟。
先把思路写成伪代码:
- 读取一个叫 article.txt 的文件,得到字符串。
- 用
split()按空白字符把文章切成单词列表。 - 遍历单词列表,用一个字典记录每个单词出现次数。
- 按出现次数从高到低排序,取出前 3 个。
- 打印结果。
这个项目把前面学的字符串、列表、字典、循环、函数、切片、排序全都串起来了。第 5 天能跟着这个思路走通,就说明你的基础知识开始变成生产力。
5.2 完整参考代码与逐行讲解
先在当前目录下新建一个article.txt,随便写几句话,比如:
python is fun and python is easy today is the fifth day然后创建一个word_counter.py,输入下面代码:
def read_file(filename): with open(filename, "r", encoding="utf-8") as file: return file.read() def count_words(text): words = text.split() word_count = {} for word in words: word_count[word] = word_count.get(word, 0) + 1 return word_count def top_words(counts, n=3): sorted_items = sorted(counts.items(), key=lambda item: item[1], reverse=True) return sorted_items[:n] def main(): text = read_file("article.txt") print("总字符数:", len(text)) print("总单词数:", len(text.split())) for word, count in top_words(count_words(text)): print(f"{word}: {count}次") if __name__ == "__main__": main()逐行说几个关键点。
open(filename, "r", encoding="utf-8")里的encoding="utf-8"能避免很多中文路径或内容的编码问题,建议每次读写文本都写上。with 语句负责自动关闭文件,比裸 open 再 close 更安全。
word_count.get(word, 0)这段是“有则取值,无则返回 0”的简写。它比word_count[word] += 1更安全,因为如果字典里还没有这个键,直接取会抛 KeyError。用 get 就能在第一次遇到某单词时返回 0,然后再加 1 变成 1。这种写法你以后会一直用到。
sorted(counts.items(), key=lambda item: item[1], reverse=True)是按字典的 value 降序排序。counts.items() 得的是很多 (单词, 次数) 的元组,lambda 指定排序依据为元组里的第二个元素,即次数。最后[:n]取出前三个。
第 5 天如果看 lambda 觉得吃力,也可以先写成普通函数,但建议第一次见到就理解它在干什么:一个匿名的小函数,在这里只是告诉 sorted “按哪个值排”。这个不要求你立刻自己会写,但见过后再遇见就不陌生。
最后那个if __name__ == "__main__":是 Python 脚本的标准写法,意思是:只有当这个文件被直接运行时才调用 main()。如果你以后把它当模块导入到别处,它就不会一上来就执行统计。先不用理解得太深,按这个格式抄下来就行。
5.3 文件读取和中文分词的后续扩展
运行这个脚本时,你可能会遇到的问题之一就是文件路径。如果你把article.txt放在脚本同一目录下,直接用文件名就行。如果你的文件放在别处,Windows 下的路径要注意反斜杠:
# 错误写法 # text = read_file("C:\Users\me\article.txt") # 正确写法一:双反斜杠转义 text = read_file("C:\\Users\\me\\article.txt") # 正确写法二:使用原始字符串 text = read_file(r"C:\Users\me\article.txt") # 更推荐的写法:用 pathlib from pathlib import Path text = Path("article.txt").read_text(encoding="utf-8")pathlib 是 Python 面向对象的文件路径处理方式,第 5 天可以先知道,后面越用会觉得越香。它不需要你手动拼路径字符串,也不怕反斜杠问题。
如果你的文件内容特别多,第 5 天可以先不考虑性能,能跑通已经赢了。想统计中文文本出现频率,text.split()按空格分会让一句话黏在一起,此时可以引入第三方库 jieba 做分词,比如:
import jieba words = jieba.lcut(text)不过那已经是你学完更多基础之后的事了。今天先把这个英文版项目跑起来,把前端到后端整条链路打通,收获比想象中大得多。
6. 新手高频报错与排查心得
6.1 别怕报错:先读最后一行
我第 5 天最大的进步,就是不再把报错当“世界末日”。其实 Python 的 traceback 是它给你的免费线索,里面藏着解决问题的关键信息。
看到报错时,先深呼吸,然后按这三步处理:
- 看最后一行,那里挂着异常类型和一句话描述,比如
IndexError: list index out of range。 - 从下往上翻,找到
File "xxx.py", line 行号,它会告诉你是哪个文件、哪一行出了问题。 - 回到代码对应行,检查是不是索引越界、类型不对、变量名拼错,或者漏了 return。
举个例子,如果看到:
File "test.py", line 6, in <module> print(name) NameError: name 'name' is not defined那你要做的事,就是去看看第 6 行前是不是变量名写错了,或者这个变量压根没赋值。很多时候问题就这么简单。
6.2 Python 环境与安装类问题速查
第 5 天你可能已经折腾过几个第三方库了,比如有人建议你安装 numpy、cv2 之类的。我在这里把常见的环境问题列一下,后面遇到直接查表。
首先是“python 不是内部或外部命令”。这个几乎都是因为安装 Python 时没有勾选Add Python to PATH。解决办法有两个:一是重新运行安装包,勾上那个选项;二是手动把 Python 安装目录和它的 Scripts 子目录加到系统环境变量 PATH 里。装了之后记得重开命令行窗口,否则不会立即生效。
第二个是pip install 某个包时提示No matching distribution found。这通常是默认源不稳定,可以换成国内镜像源:
pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple第三个是 Windows 安装 Python 时遇到0x80070643之类的错误。这个错误跟系统更新环境有关,常见于旧版 Windows。我的建议是:不要只依赖微软商店,可以直接从 Python 官网下载完整安装包,右键“以管理员身份运行”重新安装。
如果你用的是 Linux 系统,安装 Python 可以考虑系统包管理器,比如sudo apt install python3,或者用 pyenv 管理版本。新手阶段不需要自己手动编译,容易耗掉大量耐心。
6.3 第 5 天最常见的 5 个运行时报错
把下面这张表截图保存,写代码时遇到对应问题,直接对照着改。
| 报错 | 含义 | 解决方法 |
|---|---|---|
NameError: name 'x' is not defined | 变量 x 没定义或拼写错误 | 检查变量名是否一致,确认是否忘记赋值 |
TypeError: can only concatenate str (not "int") to str | 字符串和整数不能直接拼接 | 用str()把数字转字符串,或用 f-string |
ValueError: invalid literal for int() ... | int() 不能转换当前字符串 | 确保字符串内容是纯数字,比如"123" |
IndexError: list index out of range | 索引超过列表长度 | 打印len(lst)检查长度,别写死索引 |
AttributeError: 'NoneType' object has no attribute '...' | 函数返回了 None,你却调用它的方法 | 检查函数是否有 return,是否真的返回了对象 |
前四个都是入门高频,第五个很多新手遇到时最懵。比如你写:
print(len(text.split()).lower())如果text.split()没有问题,这不会报错。但如果你把早期函数的返回值没有 return 直接拿来操作,它就会变成 None,然后你想调用.lower()或.append(),Python 就会告诉你 NoneType 没有这个方法。这时侯不要怀疑人生,先回头看看操作对象是不是不该为 None。
第 5 天还有一个排查技巧特别适合新手,我习惯叫它“拆开做”。遇到一个复杂表达式报错,比如:
print(sorted(counts.items(), key=lambda item: item[1], reverse=True)[:3])如果你不确定哪里出问题,拆成多行:
items = counts.items() sorted_items = sorted(items, key=lambda item: item[1], reverse=True) top3 = sorted_items[:3] print(top3)这样每个中间变量都能单独打印,看到哪一步不对,就能快速定位。别觉得拆开写很“幼稚”,真正的生产代码也是人写的,可读性永远比花式一行流更重要。
我在第 5 天学完之后,最深的一个体会是:搞定一个程序的关键,不是把所有语法都背下来,而是知道去哪里看报错、敢不敢去改动代码验证猜测。如果你也能做到这一点,Python 入门路上最难的那道心理坎,基本就过去了。
我个人最后还有一个小小的“加练”建议:今天跑通文本统计器之后,把输出前三改成前十,把按单词统计改成按字母统计,再改一改,你就会发现哪些地方是死记硬背,哪些地方是真的懂了。学习编程这件事,自己动手改一行,比盯着教程看十遍有用得多。