ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Python零基础入门:条件判断、循环与函数实战指南

Python零基础入门:条件判断、循环与函数实战指南 这一篇笔记标题叫《0基础学-Python笔记三》是接着前两篇往下走的。前两篇里你已经完成了Python下载安装、vscode python环境配置并且搞懂了print输出、Python定义变量和类型转换。可能你已经能写出几行让电脑算数的代码但问题也随之而来程序只能一行一行从上往下执行遇到重复的事情只能复制粘贴程序出错就当场中断。第三篇重点练这几件事条件判断、循环、函数还有出错后怎么读报错。把这些走通后你就能写猜数字、生成九九乘法表、自动分类文件这类真正“有用”的脚本。如果你也是零基础前面两篇的代码已经跟着敲过可以直接往下看如果中途断档了也没关系遇到解释器的用法我会重新提一句当成查漏补缺也可以。1. 学习路线回顾第三篇到底要练哪些Python基础语法1.1 为什么很多教程把流程控制当“分水岭”前两篇我们写的代码本质上是“线性执行”从文件第一行开始一行一行跑到最后。这种代码能完成简单计算但完全谈不上“智能”。你想让程序根据分数给出不同评语它做不到你想让它把1加到100它只会让你手动写100行加法你想让它重复读取十个文件也只能复制粘贴十遍。真正的程序必须有能力在多个路径里做选择也必须有能力让同一段代码反复执行。条件判断和循环就是编程语言里的两条腿。学了它们之后程序才从“计算器”变成“逻辑机”。很多零基础的人学到这儿会突然觉得代码变得有点绕了这很正常——不是你变笨了而是你的大脑开始尝试站在计算机的角度思考执行顺序。这个转变需要一点时间但一旦跨过去后面学函数、学数据结构、学爬虫都会顺很多。所以第三篇不追求知识点多核心就一件事把“顺序、分支、循环”这三种程序结构弄到自己能轻松写出来的程度。1.2 运行代码之前先把环境这几个位置核对一遍开始敲本笔记的代码前建议顺手做一次环境自检不然代码写对了却因为环境问题反复报错很打击信心。第一确认当前用的Python版本。Windows下按WinR输入cmd回车执行python --versionmacOS或Linux终端里执行python3 --version。能看到类似Python 3.11.x或更高版本就没问题。第二在VSCode里按CtrlShiftP输入Python: Select Interpreter选择你安装的那个解释器不要让它默认在一个虚拟环境里出不来。第三给学习笔记单独建一个文件夹比如python_notes所有练习文件都放里面。别小看这个习惯Python的模块导入、文件操作都和你当前的工作目录有直接关系乱放文件后面会出很多奇怪问题。如果你已经装了Python但命令行还是提示找不到命令多半是安装时没勾选“Add Python to PATH”。这种情况不需要重装也可以直接卸载重装一次勾选上这个选项。我遇到过不少朋友卡在这里其实和代码能力没关系纯粹是环境变量的问题。2. 条件判断怎么写才不容易错if、elif和常见真假陷阱2.1 if…elif…else的固定写法冒号、缩进、赋值别写成等号条件判断能让程序根据结果走不同分支。Python里的基本结构是if、elif、else其中elif是“else if”的缩写可以有多个。看一个最简单也最典型的成绩判断score 85 if score 90: print(优秀) elif score 60: print(及格) else: print(需要加油)这段代码的逻辑是先判断score是否大于等于90成立就执行第一个分支不成立再判断是否大于等于60还不成立就走else。初学者最容易在这段代码上犯三个错。第一个错是忘记冒号。if、elif、else那行结尾必须有一个英文冒号这是Python固定语法没有冒号解释器根本不知道你的分支体从哪里开始。第二个错是用Tab还是空格混着缩进。Python不用花括号它靠缩进区分代码块。同一个代码块内部缩进必须保持一致建议都用4个空格。在VSCode里如果写到一半发现报IndentationError: unexpected indent多半就是混用Tab和空格了。第三个错更隐蔽——在判断条件里写单个等号if score 90: # 错这是赋值不是比较 print(优秀)单个是赋值两个才是比较。这个错误在代码里出现时Python会直接报语法错误因为if后面必须是一个可以计算真假的表达式。2.2 真假判断0、None、空字符串会被当成False条件判断的本质是问一个问题这个表达式是True还是False。大多数时候我们写的都是比较表达式比如score 60、name 张三。但Python里还有一个很容易被忽略的规则不是只有True和False两种值才能被当作判断条件。在if后面只要是一个确定的值Python也会自动把它转成真假。常见的规则是数字0、0.0会被当成False空字符串会被当成False空列表[]、空字典{}、空元组()会被当成FalseNone会被当成False其他非零数字、非空字符串、非空容器都会被当成True这意味着你可以写出这样的代码name input(请输入你的名字) if name: print(你好 name) else: print(名字不能为空)当用户直接按回车时name是空字符串自动判断为False就会走进else提示用户。这种写法比先判断len(name) 0要简洁很多。但要提醒一句这种隐式转换虽然方便新手却容易把自己绕晕。比如数值0明明是一个有效数字在判断里却是“假”。如果代码意图是判断某个数字是否存在一定要写清楚比较条件别靠隐式转换偷懒。2.3 小场景用今天的时间和任务数写一个下班提醒条件判断光看不练没有意义我建议你立刻把编辑器打开跟着写一个带点生活气息的小脚本。假设现在是晚上8点你手头还有4个任务没处理完程序会提示你是“可以准备下班”还是“再坚持一下”。hour 20 task_count 4 if hour 18 and hour 22: if task_count 3: print(任务不多了可以准备下班) elif task_count 6: print(还有好几个任务先吃个饭再继续) else: print(任务积压太多建议拆解优先级) else: print(还没到下班时间先专注手头工作)注意这里用到了and表示两个条件同时成立如果只要其中一个成立就执行则用or取反用not。另外注意嵌套的if缩进更靠右内层判断完全独立这样程序会先判断时间段再判断任务量逻辑层次一目了然。你可以试着把hour改成23看程序输出会不会变化——这种手动改值、观察输出结果的做法就是零基础阶段最有效的练习方式。3. 用for和while实现循环别让程序只会从上往下跑3.1 for循环基础range、字符串、列表都能“遍历”for循环是Python里出现频率最高的循环。它常被用来“遍历”一个可迭代对象字符串、列表、字典都可以。最简单的例子是遍历列表names [小明, 小红, 小刚] for name in names: print(name)它会依次把列表里的元素取出来赋给变量name每取一次执行一次缩进的代码块。这里的变量名可以随便起但最好起有意义的名字不然自己下次看代码容易懵。很多时候我们不想遍历现成的列表而是想让代码运行固定次数比如打印1到100。这时就要配合range使用。for i in range(1, 101): print(i)range(1, 101)会生成从1到100的整数序列注意它是“左闭右开”也就是说range(a, b)包含a但不包含b。只写一个参数时range(5)生成0、1、2、3、4。想隔几个数取一次还可以加步长比如range(1, 101, 2)会生成1、3、5……99。这个细节是新手很爱出错的点我当年写1到100累加时就写成range(1, 100)结果总和少了100怎么查都查不出来最后才反应过来是end值没包含进去。把循环和累加结合起来就能完成“从1加到100”这件事total 0 for i in range(1, 101): total i print(total)total i等价于total total i。程序每循环一次就把当前的i加到total上。循环结束后打印total最终结果是5050。你可以在纸上手算几个中间步骤体会一下变量在循环过程中如何不断被覆盖、累加。这对零基础来说很有必要。3.2 while循环条件不满足就退出千万记得改循环变量如果循环次数一开始就能确定我建议优先选for。但你也会遇到“不知道要循环几次只知道什么时候结束”的场景比如用户输入的密码不合法就要求重新输入这时候用while更自然。while的意思是当条件成立时一直执行循环体。看一个同样做1加到100的例子total 0 i 1 while i 100: total i i 1 print(total)这里最关键的一行是i 1。没有这一行i会一直等于1i 100永远成立程序就会变成死循环窗口里疯狂刷数字只能用CtrlC强制终止。这几乎是所有学while的人都会踩的坑包括我自己第一次跑死循环时整个终端卡了半天才反应过来。那什么时候选while而不是for我的经验是如果已经知道要循环多少次比如遍历一个列表、打印固定次数用for更简洁如果循环结束的条件需要不断动态判断比如猜数字游戏里用户可能猜一次就中也可能猜几十次用while更合适。面向零基础记住这个选择标准就够了以后写复杂项目再深入。3.3 break、continue与循环else控制循环的三种手段循环不是只能傻乎乎地从头跑到尾我们还可以在合适的时候打断它。break用于立即结束整个循环跳出循环体continue用于跳过本次循环的剩余代码直接进入下一次循环。我用一个例子展示两者的区别for num in range(1, 21): if num % 4 0: continue if num 15: break print(num)这段代码会打印1、2、3、5、6、7、9、10、11、13、14、15。4的倍数因为continue被跳过当num第一次变成16时因为大于15break让循环整体结束。如果去掉continue和break程序会完整打印1到20。你可以把这段代码跑一遍把输出和预期对一下就能很直观地理解两者区别。还有一个相对冷门但很实用的写法for循环可以配else。循环正常结束、没有被break打断时else里的代码会执行如果中途被break跳出了else里的代码就不会执行。比如在数列中查找是否存在大于5的数numbers [1, 3, 4, 2] for n in numbers: if n 5: print(找到了一个大于5的数:, n) break else: print(这个列表里没有大于5的数)numbers里没有超过5的数字循环完整跑完没有触发break所以最终会打印“这个列表里没有大于5的数”。这种写法比额外设置一个“是否找到”的标记变量要清爽很多等你以后写搜索逻辑时会经常用到。4. 列表、元组、字典三种内置数据结构的核心操作4.1 列表切片、追加、删除、排序一网打尽学完流程控制你已经能控制程序的执行顺序了但程序要处理的数据往往不是孤零零的单个变量而是一组一组出现的。列表是Python里最常用的“容器”可以装字符串、数字甚至可以混着装。scores [88, 76, 95, 60] scores.append(100) # 末尾追加一个元素 scores.insert(1, 80) # 在索引1处插入80 scores.remove(60) # 删除值为60的第一个元素 scores.pop() # 删除并返回最后一个元素 scores.sort() # 从小到大排序 print(scores)关于列表新手最需要建立两个概念索引和切片。索引从0开始所以scores[0]是第一个元素scores[-1]是最后一个元素。切片则用冒号表示范围scores[1:3]会取出索引1和索引2这两个元素同样不包含结束索引3。切片比一个个访问方便得多比如想取列表前三个元素写scores[:3]即可。使用列表时我很想提醒一个容易被忽略的点remove只删除第一个匹配到的值。如果列表里有两个88你执行remove(88)它只会删掉第一个。如果删除一个不存在的值程序会报ValueError: list.remove(x): x not in list。很多时候代码突然中断不是逻辑复杂而是你删了一个本来就不存在的元素这种错误通过“先判断存在再删除”可以轻松避免。4.2 元组写错了会立刻报错的数据结构元组和列表长得很像创建时用的是圆括号coordinates (31.23, 121.47) print(coordinates[0])但元组有一个和列表最本质的区别不可变。创建之后你不能修改、删除、新增里面的元素。如果有代码试图修改元组Python会立刻抛异常就像这样coordinates[0] 30.00 # TypeError: tuple object does not support item assignment有些初学者会问既然不能改那元组有什么用我自己的理解是元组表达的是一种“定死的信息”。比如经纬度、RGB颜色值、日期里的年、月、日这些数据不应该被程序不小心改动。一旦你用元组保存就等于告诉读代码的人这里的数据是稳定的不要试图修改。另一个常见用法是函数返回多个值时自动解包def get_min_max(numbers): return min(numbers), max(numbers) lowest, highest get_min_max([3, 8, 2, 9, 1]) print(lowest, highest)函数返回了一个元组(1, 9)调用时用两个变量一次性接住这种写法在处理多个返回值时非常优雅。你看到等号左边两个变量就知道函数返回了两个结果。4.3 字典增删改查配合get方法更稳妥如果说列表是用编号来定位数据那字典就是直接用“键”来查找“值”。它的样子像一本真正的字典你查一个词就能看到对应的解释。person { name: 张三, age: 25, city: 上海 }读数据有两种方式直接用小方括号或者用get方法print(person[name]) print(person.get(age))区别在于当键不存在时person[job]会直接报KeyError而person.get(job)会返回None。如果希望缺省时有提示信息可以给get传第二个参数person.get(job, 未知)。我强烈建议新手在不确定某个键一定存在时多用get少用直接取下标。尤其是写爬虫或读取配置文件时数据结构往往会因为外部原因出现变化用get会让程序健壮很多。对字典做增删改操作也很直接person[job] 工程师 # 新增 person[age] 26 # 修改 del person[city] # 删除遍历字典时可以直接遍历键也可以用items()同时取键和值for key, value in person.items(): print(key, value)新手很容易把字典和列表搞混然后犯一个经典错误if 张三 in person以为这样能判断“张三”这个值是否存在。实际上in在字典里默认判断的是“键”不是“值”。想判断值是否存在得写成if 张三 in person.values()。我整理笔记时把这两个放在一起对比就是为了提醒大家别在这类细节上反复踩坑。5. 自定义函数把重复代码收缩成一行调用5.1 定义函数的基本三步def、缩进、return到这一步你已经可以写出几十行的程序了但很快就发现有些代码块在程序里反复出现。比如前文那个成绩判断可能不同位置都要用数字求和计算也要写好几遍。重复本身并不可怕可怕的是当逻辑需要修改时你得把所有重复地方都改一遍漏一处就是bug。函数就是解决这个问题的。把一段代码“打包”起来起个名字以后只要对着名字调用就行。看一个最简单的加法函数def add(a, b): result a b return result print(add(3, 5))定义函数有三个关键点。第一用def开头后面是函数名、圆括号和冒号函数名命名要能看出用途最好不要叫func1这种。第二函数体必须缩进未缩进的代码不属于这个函数。第三用return把结果返回给调用者如果没有return函数会默认返回None。很多刚学到函数的同学会困惑我明明在函数里打印了结果为什么调用后外部还是拿不到原因就是没有return。你可以把函数理解成一个“加工车间”原料从参数传进去加工结果必须通过return这个传送带送出来。如果只在车间里喊一声外面当然什么也接不到。5.2 默认参数、关键字参数和可变参数Python的函数参数很灵活。可以给参数设置默认值这样调用时就不必每次都传def greet(name, greeting你好): print(greeting , name) greet(张三) greet(李四, greeting早上好)第二个调用里用了“关键字参数”的写法明确指定把早上好传给greeting。当函数参数比较多时这种写法能避免记错参数顺序代码可读性也更好。还有一个必须单独拎出来讲的坑默认参数不要用可变对象比如列表、字典。看下面这个反例def append_item(item, target[]): target.append(item) return target print(append_item(1)) print(append_item(2)) print(append_item(3))你可能以为每次调用都会新建一个空列表所以三次调用的结果是[1]、[2]、[3]。但实际输出是[1] [1, 2] [1, 2, 3]原因在于默认列表在函数定义时只创建一次后续调用如果没有传入新列表所有修改都会落在同一个列表对象上。正确写法是默认参数设为None在函数内部再新建列表def append_item(item, targetNone): if target is None: target [] target.append(item) return target这个坑在网络上一搜一大把但很多人只记住了结论不理解原因。现在你知道了默认参数是函数定义时创建的外部对可变默认参数的修改会被保留下来于是函数就像有了“记忆”但这份记忆不是我们想要的还特别难排查。5.3 函数作用域想在函数外面拿里面的变量先return作用域是学函数时的另外一个难点。简单说函数内部定义的变量默认只能在函数内部使用外面访问不到。看这段代码def test(): message hello return message # print(message) # 这里会报 NameError函数执行完内部的message生命周期就结束了。即使你在调用test()之后马上打印message也一样找不到这个名字。想要拿到它唯一正确的方式就是把它通过return返回出来并在调用时用一个外部变量接住。反过来函数内部能不能读取外部变量能可以读到一个“全局变量”。比如你在一开始定义了一个company_name Python学习社函数里打印这个变量是没问题的。但如果你想在函数内部修改全局变量的值就需要用global声明。我个人的经验是想清楚要不要用global之前先问自己这个值是不是必须被函数修改多数情况下更好的设计是把这个值作为参数传进函数然后用返回值接结果。全局变量过多会让程序变得很难追踪你在函数里改了它其他函数再用时就已经变了排查起来像猜谜。5.4 综合练习用函数实现一个判断质数的小工具又到了动手时间。现在我们结合前面章节的条件、循环和函数写一个判断质数的小代码。质数是大于1且只能被1和自身整除的自然数比如2、3、5、7是质数4、6、8不是。def is_prime(n): if n 2: return False for i in range(2, n): if n % i 0: return False return True nums [2, 4, 7, 9, 11, 20] for num in nums: if is_prime(num): print(num, 是质数) else: print(num, 不是质数)拆解一下逻辑当n小于2时直接返回False因为质数必须大于1然后用for i in range(2, n)逐个检查从2到n-1这些数看n是否能被某个i整除如果能就说明它不是质数立即return False退出函数循环结束后都没有遇到能整除的数说明是质数返回True。注意函数里有两个return一个在循环内部一个在循环结束后。很多人会担心循环里已经return False了后面还能执行到return True吗能因为return会立即终止整个函数所以只有循环完整结束、没有提前退出时才会走到最后一个return。试着把is_prime改成用while实现再看看效果这种“一题多改”练习法比一直往后赶进度要踏实得多。6. 异常处理三件套与新手调试技巧6.1 try/except/else/finally的基本用法程序只要一收到非法输入就会中断并甩出一大段红色报错。有很多初学者被这种场面吓住觉得自己写错了天大的问题。其实报错反而是Python在努力帮你——它明确告诉你哪一行出了问题。我们可以在代码里主动“抓住”异常避免程序崩溃这就是异常处理。先看一个典型的错误场景num int(input(请输入一个整数)) result 100 / num print(计算结果, result)如果用户输入的不是数字int()会抛ValueError如果输入0100 / num会抛ZeroDivisionError。不管是哪一种程序都会直接中断后面的代码都不执行了。换成异常处理后情况就不同了try: num int(input(请输入一个整数)) result 100 / num print(计算结果, result) except ValueError: print(输入的不是整数请重新运行程序) except ZeroDivisionError: print(除数不能为0) else: print(没有异常计算顺利完成) finally: print(这条内容无论如何都会打印)结构并不复杂把可能出错的代码放进try如果出错Python会寻找匹配的except分支并执行里面的内容else里的代码只在没有异常时执行finally比较特殊它不管程序有没有异常、有没有提前return都会在最后执行所以常用在文件读取、网络请求这类需要收尾的场景。写文件时即使写操作出了问题也要把文件对象关掉放到finally里最稳妥。6.2 新手最容易看到的6类异常一张表对照排查很多时候程序报错并没有进入我们自己写的except而是直接终止。这并不代表你写得差而是说明这类异常没有被预料到。掌握常见异常的表象和原因排查速度会快很多。我把零基础阶段出现概率最高的异常整理成了一张速查表异常类型出现场景排查方向NameError使用了未定义的名字检查变量名是否拼错函数内变量有没有返回TypeError类型不匹配、参数个数不对字符串和数字不能直接相加调用函数时参数是否齐ValueError值本身不合法比如int(abc)试图把非数字字符串转整数IndexError索引超出范围列表只有3个元素却访问了list[5]KeyError字典里访问了不存在的键先用in判断或用get()方法ZeroDivisionError除数为0检查除数是否可能为0提前判断SyntaxError语法错误检查冒号、括号、引号、缩进通常最后一行提示很准看到SyntaxError时不要慌它大概率是代码格式问题。比如上一行少了圆括号下一行才被发现有语法错误中文标点和英文标点混用也是重灾区。你可以在VSCode里把语法高亮打开中文标点通常看起来比英文标点宽一截一眼就能分辨出来。6.3 报错调试三板斧print大法、注释排除、看最后一行最后分享三个调试技巧都是我实际写Python时天天在用的算不上一劳永逸但对付入门阶段的“灵异事件”非常够用。第一个技巧是“print大法”在关键位置打印变量的值看看程序执行到这里时变量到底等于多少。很多人写的函数逻辑没错但调用后结果不对就是因为传入的数据和自己预期的不一样。你只要在函数入口处加一行print(传入的值是:, value)往往立刻发现真相。等确认问题修好再把调试用的print注释掉就好。这方法虽然原始但比任何高大上的调试器都直观尤其适合还没学会用断点的零基础阶段。第二个技巧是“注释排除”当一段代码报错但你不确定是哪里引起的可以先把可疑的一整段注释掉然后逐步取消注释观察错误什么时候重新出现。千万不要盯着屏幕瞎猜。把错误范围缩小到几行之内你再仔细看那几行代码大概率自己就能找到问题。我曾经写一个数据处理脚本逻辑很长打印出来的结果却差得离谱。后来把代码分成五段一段一段解开注释跑终于定位到是一个布尔条件少写了一个not这种问题不缩小范围光靠肉眼几乎发现不了。第三个技巧是“看报错最后一行”。Python的报错信息习惯是最后一行写异常类型和简明原因比如TypeError: can only concatenate str (not int) to str前面几十行是调用栈新手往往不用全部看懂。只要从最后一行开始读看到错误类型再结合那个“发生错误的文件名与行号”去定位效率会高很多。等你慢慢熟悉了再回头看栈里的中间函数调用记录就能搞清错误是怎么一层层传上来的。我后来带零基础朋友时常让他们把报错里面“信息的最后一行文字”念出来给我听而不是直接把几百行报错截图丢过来。太多人看一眼红色报错就慌了。其实Python更像一个啰嗦但诚实的助手它把所有线索都告诉你了你只需要静下来抓住最后一行再回到代码那一行跟前把“可能出错的变量”和“实际运行时的值”对照一遍大多数问题都能在几分钟内解决。学Python到这儿你已经不再是只能照着例子抄的小白你能让代码自己判断让它反复执行某段逻辑能把数据装进列表、元组、字典也能把常用代码封装成函数就算程序崩溃也懂得怎么看异常、怎么缩小排查范围。这些东西组合起来足够支撑你写出不少小而实用的脚本了。如果你是按这篇笔记一路敲下来的我建议你这几天就试着把上一篇文章里学到的数据类型和今天这里学的循环、函数放在一起做一个自动整理文件或生成随机密码的小工具。这种“把知识点拼成作品”的过程才是零基础阶段最宝贵的一步。
返回列表