
如果有人拿着“python第五次作业”这个词来搜索我几乎可以断定他正处于Python入门课的前半程。前四次作业大概把变量、赋值、input输出、条件判断、循环都过了一遍语法上已经能写出“能跑”的代码了但距离“写出像样的程序”还有一段肉眼可见的距离。第五次作业往往是一个分水岭题目开始要求你处理真实数据、做类型判断、处理字符串而不是单纯打印几行星星、算个阶乘。这个阶段的作业考察的核心往往就三件事类型转换、字符串处理、输入数据的健壮性。我见过太多人在第五次作业上栽跟头不是题目有多难而是对Python的数据模型理解得不够深。这篇就拿一份典型的第五次作业出来拆解一遍——题目涉及用户输入、类型转换、字符串格式化、边界值处理所有代码我都跑过运行结果直接贴出来。不管你手头的作业具体是什么题这篇文章都能帮你把背后的原理吃透写出来的代码比班里九成的人都干净。1. 作业背后的真实考点课程进度到这里到底在考什么Python课程设置到第五次作业时间点通常在开课后的第四到第六周。这个阶段的教学进度我根据带过的几百个初学者的反馈基本已经推进到了这些内容内置数据类型int、float、str、bool、list基本用法类型转换int()、float()、str()、bool()的使用场景字符串方法split、strip、replace、lower、upper等f-string格式化输出input()的返回值特性基本的异常处理和边界条件判断这个进度是经过精心设计的。第五次作业之前学生已经掌握了顺序、分支、循环三大结构可以写出完整的程序流程了但写出来的东西是“玩具级”的——数据都是写死在代码里的。第五次作业开始程序必须接受用户的输入对输入做校验和清洗再经过计算和格式化输出。这是从“程序跑给自己看”到“程序跑给别人用”的转变。我见过不少人对这个阶段不以为然觉得“能跑就行”。但第五次作业恰恰是区分“会抄代码”和“会写代码”的分水岭。这道题做完你应该建立起几个很关键的认知输入是不可信的。用户可能输入数字、字母、负数、小数、空字符串、超长字符串你的程序面对所有这些情况都不能崩溃。类型转换不是万能的。int(3.14)会报错float(abc)也会报错。你必须在转换之前就预判可能出现的错误。字符串操作要熟练到不用查文档。第五次作业里的大量得分点都藏在字符串方法的灵活运用上。一个很现实的问题是大部分初学者做第五次作业时最大的障碍不是语法写不出来而是“想不到还能这么处理”。说白了就是见过的解法和模式太少。这篇文章后面给出的示例我会刻意覆盖最常见的几种处理套路你可以在自己的作业里直接套用。2. 类型转换的原理细节为什么int(3.14)会失败而float(3)会成功2.1 显式转换和隐式转换Python在这件事上比别的语言更严格很多从C或Java转过来学Python的人一开始会对Python的类型转换感到困惑。C语言里int和float可以轻易地相互赋值编译器自动帮你转Java里也有自动装箱拆箱那一套机制。但Python是一门强类型语言它不轻易做隐式类型转换。我说个最简单的例子a 5 b 10 print(a b)这段代码运行会直接抛TypeError: unsupported operand type(s) for : int and str。在一些弱类型语言里这个表达式会把5自动转成5然后拼接成510但Python拒绝这么做。它宁愿报错也不愿意替你做模糊的类型判断。这个“严格”的设计在第五次作业里非常关键。当你从input()拿到用户输入时得到的一定是一个字符串哪怕用户输入的是数字age input(请输入你的年龄) print(type(age)) # class str print(age * 2) # 如果输入20输出2020而不是40这就是第五次作业里最常见的送命题——忘了input返回的是字符串直接拿去做算术运算。我在批改作业时这一条大概能让三成人的程序运行结果完全错误。2.2 int()和float()的内部解析逻辑int()和float()是第五次作业里使用频率最高的两个转换函数。你真的理解它们在做什么吗int(x)做的事情把x转换为整数。如果x是字符串它会尝试解析字符串中的数字内容如果x是浮点数它会截断小数部分向零取整而不是四舍五入。print(int(42)) # 42 print(int(-7)) # -7 print(int(3.99)) # 3注意不是四舍五入 print(int(3.14)) # ValueError: invalid literal for int()最后一行很能说明问题。int()解析字符串时只接受整数形式的字符串不接受带小数点的字符串。很多人写作业时想让用户输入一个成绩直接写int(input(请输入成绩))用户一输个86.5程序就崩了。如果题目允许小数你应该用float()。float(x)的逻辑类似但它更宽容——它能解析整数形式的字符串也能解析小数形式的字符串甚至能解析科学计数法print(float(42)) # 42.0 print(float(3.14)) # 3.14 print(float(1e3)) # 1000.0 print(float(abc)) # ValueError2.3 进制转换这一层很多人没意识到int()还有第二个参数第五次作业如果涉及进制转换的题目——比如把二进制字符串转成十进制——你必须知道int()可以接受第二个参数指定进制binary_str 1011 decimal int(binary_str, 2) print(decimal) # 11 hex_str ff decimal int(hex_str, 16) print(decimal) # 255第二个参数的范围是从2到36。这个特性在实际工作中也有用比如处理颜色值、二进制日志数据等。但不少初学者只知道int(x)的单参数用法做进制转换题时绕了很大弯路——有的人甚至用循环一位一位去算权重。2.4 布尔转换的truthiness机制什么时候一个值被认为是Falsebool()这个函数同样值得聊。Python里任何对象都可以被用来做布尔判断不需要显式调用bool()——if语句、while循环的条件都会隐式地做这个转换。规则是这样的以下值在布尔上下文中被视为FalseFalse、0、0.0、空字符串、空列表[]、空元组()、空字典{}、空集合set()、None。其他的所有值都是True。这个机制在写“判断用户是否输入了内容”时非常有用user_input input(请输入内容) if user_input: # 非空字符串才进入这个分支 print(你输入的是, user_input) else: print(输入不能为空)不用写user_input ! 这种啰嗦的判断直接if user_input就能区分空与非空。说实话我在日常工作里判断集合、判断字符串是否为空都是这么写的很少显式地去比较。2.5 一个必须养成的习惯转换前先验证类型转换最大的坑在于转换失败会直接抛异常程序就终止了。第五次作业开始你应该养成“先验证再转换”的习惯用感叹号表达就是不要盲目信任任何输入。raw input(请输入成绩) if raw.replace(., , 1).isdigit(): score float(raw) print(有效成绩, score) else: print(输入的不是有效数字)这段代码用了字符串的isdigit()方法判断是否为纯数字但isdigit()只认数字字符不认小数点。所以先remove掉一个小数点再判断这是处理这个问题的常见技巧。更可靠的方案是用try/except包裹转换过程这个我在后面会专门讲。3. 字符串处理第五次作业真正的主战场几个方法与陷阱一次讲透3.1 切片左闭右开的边界问题第五次作业里经常要求截取字符串、反转字符串、判断回文等。这一切的基础都是切片操作。切片语法是s[start:end:step]核心记住一句话包含start不包含end。这个左闭右开的设计跟range()是一致的也是Python的通用惯例。入门阶段最常见的错误就是把边界搞混s Hello, Python # 想取前5个字符 print(s[0:5]) # 输出Hello print(s[:5]) # 输出Hellostart可以省略 # 每隔一个字符取一个 print(s[::2]) # 输出Hlo yhn反转字符串是切片操作里最经典的一道题s Python print(s[::-1]) # 输出nohtyP这里的-1步长表示从右往左遍历start和end都省略意味着遍历整个字符串。就这么一行比用循环反转要干净得多。3.2 字符串的“不可变”到底意味着什么第五次作业还会有一个考点字符串是不可变类型。你调用replace()、upper()、strip()这些方法时Python会创建一个新的字符串并返回而原字符串不会发生变化。很多初学者在这里吃苦头name Alice Smith name.strip() print(name) # Alice Smith 两边空格还在正确写法是重新赋值name name.strip()建议把这条规则刻进脑子里字符串的任何方法都不会修改原字符串你需要用返回值去接收处理结果。这个特性刚开始有点拧巴但学久了就会明白它带来的好处——字符串可以安全地作为字典的键不用担心被意外修改。3.3 split()和join()处理“有格式输入”的两板斧第五次作业常常会出现这类题目用户输入一系列数字用逗号分隔或者输入一句话按空格拆成单词。这时split()就是你的主力工具data input(请输入多个数字用逗号分隔) numbers data.split(,) # 得到一个字符串列表 print(numbers) # 比如 [12, 34, 56]但注意一个细节split()出来的列表元素还是字符串后续做计算时还得再转一次。所以常见套路是配合列表推导式numbers [float(x) for x in data.split(,)]这里列表推导式的作用是把列表中的每一个字符串元素用float()转换一遍得到一个新的浮点数列表。这个写法干净利落比写for循环一行行转换要简洁。split()还有第二个参数指定拆分次数。比如只拆分第一次出现逗号的地方s a,b,c,d print(s.split(,, 1)) # [a, b,c,d]这个特性在解析键值对、处理时间字符串时很有用。与split()相反的操作是join()注意它是字符串的方法不是列表的方法语法稍微反直觉words [Hello, Python, World] sentence .join(words) print(sentence) # Hello Python World用join()而不是用加号拼接列表里的元素是明显的性能优化——字符串是不可变类型用拼接会不断创建新字符串效率低而join()会预先计算好总长度一次性生成结果。虽然第五次作业的数据量可能看不出性能差距但这个习惯值得早点养成。3.4 格式化输出f-string的完整玩法第五次作业一定会要求格式化输出以前老教程会教你用%占位符或者format()方法现在主流是f-stringPython 3.6。f-string在字符串前加一个f前缀用花括号{}直接引用变量name Alice score 87.5 print(f学生{name}的成绩是{score}) # 输出学生Alice的成绩是87.5f-string真正厉害的地方在于花括号里可以嵌表达式甚至可以调函数print(f成绩取整后是{int(score)}) print(f成绩四舍五入到1位小数是{score:.1f}) print(f成绩的百分比形式是{score/100:.2%})格式化规格符语法是冒号后面的部分常用的几个我列个表格式说明示例结果含义:.2ff{3.14159:.2f}3.14保留两位小数:.0ff{3.5:.0f}4取整四舍五入银行家舍入法有差异初中阶段不用太纠结:10f{hi:10}见右右对齐宽度10:^10f{hi:^10}见右居中对齐宽度10:03df{42:03d}042数字补零到3位:.2%f{0.1234:.2%}12.34%百分比形式:,f{1234567:,}1,234,567千位分隔对齐操作在处理输出表格时尤其好用。第五次作业有时候会要求“输出格式对齐美观”这一列的表就能直接派上用场。我当年教学生时总会强调代码能跑是最低标准输出好看是加分项数据不出错才是核心。3.5 转义字符和原始字符串遇到文件路径和换行时的救命稻草字符串里还有一些跟转义相关的坑第五次作业里如果涉及处理特殊字符就能遇到。\n代表换行\t代表制表符代表双引号。这些是最基本的。但有一个坑值得单独讲当你在Windows下处理文件路径时反斜杠会被当成转义符比如