☰
Python经典实例精讲:从基础语法到工程实践,吃透20例胜过刷100例
2026/10/31 10:49:11 网站建设 项目流程

简介:这是一份面向Python初学者与进阶开发者的经典实例代码合集,共包含96个可直接运行的.py脚本,全部封装于一个zip压缩包中,整体大小仅53KB,轻量易用。实例覆盖Python基础语法、常用数据类型操作、控制结构与函数定义、模块与包管理、面向对象编程、文件读写与异常处理、数据库连接与操作、网络请求、数据可视化等常见开发场景,代码风格简洁清晰,具备较强的可读性与可维护性。每个脚本以JCP编号命名,便于按主题索引;其中既有变量、列表、字典、元组等基础练习,也有类继承与封装、SQLite/MySQL交互、Pandas数据分析及Matplotlib绘图等进阶案例。初学者可跟随实例循序渐进地巩固核心语法,有经验的开发者也能快速提取所需脚本作为项目参考或优化模板。目前已有758人学习下载,适合日常自学、课堂教学、课后练习以及实际项目中的快速查用。

1. 你的第一份Python实例清单,为什么不该贪多

很多初学者拿到“Python经典实例代码汇总100例”这类资料,第一反应是赶紧存下来,然后从第1例开始往后刷。我见过太多人刷到第30例就放弃了,不是因为不够努力,而是因为这种刷法本身就有问题——你只是在看代码,不是在练代码。

我自己的经验是,所谓的“100例”真正有价值的可能只有三四十例,剩下的要么是重复的语法点,要么是为了凑数硬塞进来的偏门用法。与其追求数量,不如把最核心的十几个经典实例彻底吃透,每个都亲手敲一遍、改一遍、跑一遍,收获比机械刷完100例大得多。

这篇文章我就用实际可运行的代码,把Python里最值得反复练的经典实例拆开讲一遍。覆盖输入输出、字符串处理、循环逻辑、函数设计、文件操作、异常捕获这几个最高频的语法点,每个实例都附带我踩过的坑和优化经验。不需要你有任何基础,只要装好了Python就能跟着跑起来。

还没装环境的,我后面有一节专门讲Python安装和IDE选型,新手照着做就行。装好的可以直接跳到第3节看代码。

2. 环境准备:装对Python,少走一半弯路

2.1 版本选择与下载要点

先说安装。现在Python已经到了3.12时代,网上很多老教程还在讲Python 2.x,那些东西真的不用看了。你只需要记住一个原则:装最新稳定版。去Python官网(python.org)下载页面,点Downloads,选Windows或macOS对应的最新版本就行。

我提醒一个很容易踩的坑:安装到第一步时,界面底部有个“Add Python to PATH”的复选框,必须勾上。不勾的话,你之后在命令行输入python会提示找不到命令,新手很容易卡在这一步然后心态崩了。勾上之后一路Next就可以了。

Linux用户直接用包管理器装,Ubuntu/Debian是sudo apt install python3,CentOS/RHEL是sudo yum install python3,不同发行版包名可能略不一样,装完执行python3 --version验证一下。注意Linux下一般要敲python3而不是python。

装完验证也很简单,打开终端或命令提示符,输入python --version(Windows)或python3 --version(Linux/macOS),能看到版本号就说明装好了。

2.2 IDE选型建议

编辑器这块我的建议很直接:新手别折腾VSCode和PyCharm的插件配置,先用IDLE。Python自带IDLE,装好就有,打开就能写,零配置,够你跑完前三周的所有练习。

等你对语法有感觉了,再迁移到VSCode,装上Python官方插件就够用。PyCharm社区版是免费的,功能全,但启动慢、内存占得多,新手阶段没必要上。我见过太多人光研究IDE配置就花了两天,真正的代码一行没写,本末倒置了。

另外建议你装一下Jupyter Notebook,pip install jupyter然后运行jupyter notebook就能起一个交互式编程环境。它特别适合边写边看输出,学语法阶段体验极佳,但要注意它是单核执行的,跑大数据分析和模型训练性能不够,那是后话。

3. 核心实例拆解:练透这10个,胜过刷完100例

3.1 九九乘法表:循环嵌套与格式化输出的入门必修

九九乘法表是Python学习者的第一个“仪式感”程序,看起来简单,但能把for循环嵌套、range()函数、字符串格式化、end参数这四个知识点全部串起来。

# 九九乘法表 - 经典版本 for i in range(1, 10): for j in range(1, i + 1): print(f"{j} * {i} = {j * i}", end="\t") print() # 换行

运行结果:

1 * 1 = 1 1 * 2 = 2 2 * 2 = 4 1 * 3 = 3 2 * 3 = 6 3 * 3 = 9 ...

这里有两个关键点。第一,内层循环的range(1, i+1)决定了每行输出几项,它是跟着外层i变化的,这就是嵌套循环的核心逻辑——内层循环的次数由外层变量控制。第二,end="\t"表示打印完不换行而是输出一个制表符,end参数很多人第一次见,它接受的其实是print函数输出末尾的字符,默认是\n换行符。

我建议你试试这三处改动,理解会立刻加深:

  • 把内层range(1, i+1)改成range(1, 10),观察输出变成什么样
  • 把内层和外层的i、j互换位置,输出会变成按列排列
  • 用format()替换f-string:print("{} * {} = {}".format(j, i, j*i), end="\t")

三道题做完,你对循环的理解会从一个“背过的语法”变成“自己的逻辑”。

3.2 统计字符串中各类字符的个数:字符处理的经典综合题

这个实例是面试题里的常客,也是字符串处理的基础功。它要求统计一段文本中英文字母、数字、空格和其他字符的数量,综合考察了字符串遍历、isalpha()、isdigit()、isspace()这几个判断方法。

def count_chars(text): letters = digits = spaces = others = 0 for ch in text: if ch.isalpha(): letters += 1 elif ch.isdigit(): digits += 1 elif ch.isspace(): spaces += 1 else: others += 1 return letters, digits, spaces, others content = "Hello Python 123! 你好,世界 " letters, digits, spaces, others = count_chars(content) print(f"字母: {letters}, 数字: {digits}, 空格: {spaces}, 其他: {others}")

注意isalpha()对中文也会返回True,因为中文字符按照Unicode的字母属性来判定。如果你只想要英文字母,需要配合条件ch.isalpha() and ch.isascii()来过滤。这个细节很多人工作两三年才踩到。

实际开发中,这类逻辑经常用在日志分析、敏感词过滤、文本预处理等场景中。比如清洗用户输入的手机号或身份证号,先用isdigit()判断是否全数字,就是这类实例的直接应用。

3.3 水仙花数与自幂数的判断:数学逻辑与枚举法的结合

水仙花数是一个三位数,它的每个位上的数字的立方之和等于它本身,比如153 = 1^3 + 5^3 + 3^3。这个实例的核心考点是如何拆解一个整数的各个数位。

def is_narcissistic(num): # 转成字符串再取每个字符,是最直观的方式 digits = [int(d) for d in str(num)] return sum(d ** 3 for d in digits) == num # 找所有三位水仙花数 result = [n for n in range(100, 1000) if is_narcissistic(n)] print(result) # 输出: [153, 370, 371, 407]

这里我特意用了列表推导式(list comprehension),它比传统的for循环加append写法简洁很多,也更容易读。现在Python社区的主流风格是优先使用推导式和生成器表达式,你要尽早习惯这种写法。

如果说不用字符串转换,也可以用数学方法逐位拆解:

num = 153 hundreds = num // 100 # 百位 tens = (num // 10) % 10 # 十位 units = num % 10 # 个位

两种方式都不难,我推荐新手两种都写一遍。字符串法代码简洁,数学法速度更快且能加深取整和取余的理解。实际业务中,从身份证号、手机号、订单号里提取特征位,用的就是这种拆解思路。

3.4 斐波那契数列:递归、迭代与缓存的对比

斐波那契数列几乎能代表一个程序员的算法水平认知。最简单的定义是递归:F(n) = F(n-1) + F(n-2),基准条件为F(0)=0, F(1)=1。但直接写递归,一旦n超过30,速度就会肉眼可见地变慢;n到40左右,直接肉眼可见卡顿,n=50就基本跑不完了。

# 递归版 - 代码最简单但效率最差 def fib_recursive(n): if n <= 1: return n return fib_recursive(n - 1) + fib_recursive(n - 2) # 迭代版 - 推荐,时间复杂度O(n) def fib_iterative(n): a, b = 0, 1 for _ in range(n): a, b = b, a + b return a # 带缓存的递归(记忆化)- 既优雅又高效 from functools import lru_cache @lru_cache(maxsize=None) def fib_cached(n): if n <= 1: return n return fib_cached(n - 1) + fib_cached(n - 2)

这里要重点理解为什么递归慢:每次调用都会重复计算大量的子问题。用fib_recursive(5)推演一次,你会发现fib(2)被算了三次。而lru_cache装饰器把每次的计算结果缓存下来,下次直接查表,就把指数级复杂度降到了线性。

我在实际项目里用递归写目录树遍历时,踩过同样的性能坑,后来加了缓存变量才解决。所以这个实例值得你反复琢磨——它教的不只是数列,而是重复计算的优化思路。

3.5 列表去重的三种姿势:从直观到优雅

Python里列表去重的方式特别多,不同写法性能和适用场景差异很大。我给你列出三种最常用的,从新手版到进阶版都覆盖到。

data = [1, 2, 2, 3, 3, 3, 4, 5, 5] # 方法1:遍历+判断(保持顺序) result = [] for x in data: if x not in result: result.append(x) # 方法2:set去重(代码简洁但顺序可能变) result2 = list(set(data)) # 方法3:字典fromkeys(保持顺序且代码简洁) result3 = list(dict.fromkeys(data))

方法2用set去重最快,但无序;如果你的数据是字符串列表,顺序变了就会很麻烦。方法3的dict.fromkeys(data)会以列表元素作为字典的键,键天然不重复,且Python 3.7以后字典维护插入顺序,所以能做到既去重又保序。这是我的首选写法。

进阶场景中,如果要对字典列表去重,没法直接用set,因为字典不可哈希。这时候可以按某个唯一键去重:

items = [{"id": 1, "name": "A"}, {"id": 2, "name": "B"}, {"id": 1, "name": "C"}] seen = set() result = [] for item in items: if item["id"] not in seen: seen.add(item["id"]) result.append(item)

数据清洗、接口去重、日志去重,这些场景在我做爬虫和数据处理时几乎天天用,这个实例虽然基础,但它是你在真实工程中离不开的底层能力。

3.6 文件操作:读写配置文件和统计词频实战

文件操作是Python进入真实世界的门槛。只会在终端打print,说明你还没接触到工程。我用统计一篇文章词频这个例子,把文件读取、字符串切分、字典操作、排序这四件事串起来。

from collections import Counter import re # 读文件 with open("article.txt", "r", encoding="utf-8") as f: content = f.read() # 把非字母字符替换为空格,再转小写 words = re.findall(r"[a-zA-Z]+", content.lower()) # 统计词频 word_count = Counter(words) # 输出前10高频词 for word, count in word_count.most_common(10): print(f"{word}: {count}次")

这段代码里我用了正则re.findall来提取字母序列,直接跳过了标点和数字,比简单地用split()干净得多。Counter是collections模块里的计数器,most_common(10)直接返回频次最高的前10项,内部做了排序,不用自己写排序逻辑。

with open() as f这种写法要养成习惯,它会在代码块结束后自动关闭文件。很多新手喜欢写f = open(...)然后忘了f.close(),短时间没事,但容易在Windows上遇到文件被占用的报错。

3.7 猜数字游戏:random模块、循环与用户输入的综合应用

写一个小游戏是保持学习兴趣最好的方式。猜数字游戏让用户猜一个1到100之间的数,程序提示大了还是小了,直到猜对。

import random target = random.randint(1, 100) attempts = 0 print("我已经想好了一个1~100之间的数字,开始猜吧!") while True: try: guess = int(input("请输入你的猜测: ")) except ValueError: print("请输入一个有效的整数!") continue attempts += 1 if guess < target: print("太小了,再大一点") elif guess > target: print("太大了,再小一点") else: print(f"恭喜你!猜对了,总共用了{attempts}次") break

这里引入了int(input(...))的组合用法,以及try/except捕获输入非数字情况的处理。初学者最容易忘掉的就是异常处理,如果用户输入了abc,直接执行int("abc")就会抛出让程序崩溃的ValueError。

我建议你把猜数字扩展成几个小版本:缩小范围版(猜错一次范围减半)、计分版(猜的次数越少分越高)、双人版(一个设数一个猜),这些变体练下来,你对while循环和break的理解会非常扎实。

3.8 冒泡排序:亲手实现第一个排序算法

虽然Python内置的sorted()已经够快,但手写排序算法是理解算法思想不可绕过的练习。冒泡排序是所有排序里最直观的,也是教学价值最高的。

def bubble_sort(arr): n = len(arr) for i in range(n - 1): swapped = False for j in range(n - 1 - i): if arr[j] > arr[j + 1]: arr[j], arr[j + 1] = arr[j + 1], arr[j] swapped = True if not swapped: # 如果这一轮没有任何交换,说明已经有序,提前结束 break return arr data = [64, 34, 25, 12, 22, 11, 90] print(bubble_sort(data))

两个细节值得讲。第一,内层循环的range(n - 1 - i)中- i是因为每一轮结束后,最大的数已经“冒泡”到了最后,下一轮不需要再比较它。这个优化能让比较次数减半。第二,swapped标志位实现“短路”,如果某轮没有发生任何交换,说明数组已有序,直接退出循环,在近似有序的数组上能大幅提升性能。这个优化叫“短冒泡”,是冒泡排序的经典改进版。

Python里交换两个变量的值,写arr[j], arr[j + 1] = arr[j + 1], arr[j]即可,不需要第三个临时变量,这是Python的元组打包与解包特性。在其他语言里你必须要写temp。

3.9 函数式编程三剑客:map、filter、lambda的实战演示

接触函数式编程之后,你的代码风格会有一个质变。map()、filter()和lambda表达式是Python函数式编程的入门三件套,我用一个给价格批量打8折为例:

prices = [199, 89, 599, 1299, 49] # 用map实现“对所有元素做统一操作” discounted = list(map(lambda x: round(x * 0.8, 2), prices)) print(discounted) # [159.2, 71.2, 479.2, 1039.2, 39.2] # 用filter实现“筛选出满足条件的元素” expensive = list(filter(lambda x: x > 100, prices)) print(expensive) # [199, 599, 1299] # 用列表推导式实现同样的效果更Pythonic discounted2 = [round(x * 0.8, 2) for x in prices] expensive2 = [x for x in prices if x > 100]

你可能会疑问:既然列表推导式能写得更简洁,为什么还要学map和filter?原因有两个。一是当你处理的是生成器而不是列表时,map和filter是惰性求值的,处理超大数据集时内存占用更小;二是很多工具库的API设计上接受函数作为参数,比如sorted()的key参数,你掌握了函数式思维才能灵活运用它们。

当然了,日常工作里我也会优先写列表推导式,因为可读性更好。两者都掌握,看别人代码不吃力,自己写也有选择余地。

3.10 类与对象:用银行账户模拟理解封装

最后一个经典实例我给到面向对象。很多初学者悟不透类有什么用,我的解释是:把数据和操作数据的方法打包在一起,就是类。用银行账户来模拟最直观:

class BankAccount: def __init__(self, owner, balance=0): self.owner = owner self.balance = balance def deposit(self, amount): if amount <= 0: raise ValueError("存款金额必须大于0") self.balance += amount print(f"{self.owner} 存入 {amount} 元,余额为 {self.balance} 元") def withdraw(self, amount): if amount <= 0: raise ValueError("取款金额必须大于0") if amount > self.balance: raise ValueError("余额不足") self.balance -= amount print(f"{self.owner} 取出 {amount} 元,余额为 {self.balance} 元") def show_balance(self): print(f"{self.owner} 的余额为 {self.balance} 元") # 使用 account = BankAccount("张三", 1000) account.deposit(500) account.withdraw(200) account.show_balance()

__init__是构造函数,self代表实例自身。我在这里故意加入了参数校验逻辑:存款和取款必须为正数,取款不能超过余额,违反就抛ValueError。这是工程中必须有的防御式编程理念。

面向对象在数据分析里用得可能不如脚本多,但一旦你开始写项目级的代码、做代码模块化,类是绕不开的组织方式。这个银行账户例子虽然简单,但它体现了类的三个核心好处:封装、状态保持、代码复用。

3.11 其他值得练的经典实例一览

除了上面十个精讲实例,我再列一批编号实例,适合在你完成精讲内容后作为日常刷手速的练习题。每个都对应一个独立语法或技巧点:

编号实例名称核心知识点
11判断闰年条件运算与逻辑运算符
12计算阶乘循环或递归两种实现
13字符串反转切片[::-1]的威力
14判断回文数字符串与数字的转换
15求最大公约数辗转相除法
16杨辉三角双层列表与行列规律
17打印菱形图案字符串居中与循环
18二分查找递归与区间的理解
19随机密码生成random与字符串拼接
20约瑟夫环循环列表的删除逻辑

这十个加前面的十个,就是我眼中“百例清单里真正有含金量的二十例”。你把它们吃透,应对大部分面试的算法现场编程环节完全够用。剩下的八十几例,本质上都是这二十例的变种,有的改个数字范围,有的换个输出格式,核心思路都是相通的。

4. 运行Python代码的正确姿势与排查技巧

4.1 三种执行方式与适用场景

写好.py文件后,你可以用三种方式运行它:

第一,在终端里执行python 文件名.py,这是最标准的方式,适合跑完整脚本。第二,在Python交互式环境(REPL)里一行一行敲,适合验证单个语法点。第三,在Jupyter Notebook里分单元格执行,适合做数据分析和边写边看的探索性编码。

我自己练手的时候,一般是先用REPL或Notebook验证逻辑,再整理成.py文件保存。这样可以随时看到中间结果,调试效率高很多。

4.2 新手最容易踩的5个坑

坑1:把文件名命名为test.py或random.py,然后运行报错。

这类名字和Python标准库模块重名,会导致import random时导入你自己的文件而不是标准库。我建议所有练习文件都起有意义的独立名字,比如guess_number.py,而不是test.py。

坑2:input()返回的是字符串,不能直接参与数学运算。

很多新手写age = input("请输入年龄: "),再if age > 18:就报TypeError了。解决方法是加一层类型转换age = int(input(...)),或者在做比较的地方用int(age)转一下。

坑3:混用空格和Tab缩进。

Python对缩进极其敏感,同一个代码块里空格和Tab混用会直接报TabError。我建议你在编辑器里统一设置为“按Tab键插入4个空格”,一劳永逸。

坑4:列表索引从0开始,越界会报IndexError。

len(list)的取值范围是0到len(list)-1,想取最后一个元素用list[-1]而不是list[len(list)],后者必然越界。

**坑5:可变默认参数。**这是进阶点的经典问题:

def add_item(item, items=[]): items.append(item) return items print(add_item(1)) # [1] print(add_item(2)) # [1, 2] —— 这里出现了诡异的现象

函数定义时items=[]这个列表只创建一次,后续调用如果没传入新列表,都会复用同一个列表对象,导致数据“串台”。正确写法是def add_item(item, items=None): items = [] if items is None else items。这是Python面试常考题,也是实际开发中很容易埋下的隐患。

4.3 用print调试的进阶技巧

新手最常见的调试手段是到处加print(),这没问题,但要注意打印的内容。推荐用f-string把变量名和值一起打印出来,不要只打值:

# 不推荐 print(price) # 不知道这个值对应什么变量 # 推荐 print(f"price = {price}") # 一目了然

还有一个很多人不知道的技巧:pprint模块。打印复杂嵌套结构时,普通print会挤成一坨,pprint会智能格式化,清晰很多。在交互式调试中,pprint比print好用几个数量级。

4.4 异常处理:让程序不因一个小错误崩溃

真实程序里用户输入是不可控的,文件可能打不开、网络可能断。用try/except捕获异常,让程序优雅处理而不是直接崩溃,是工程中必备的素养。

try: num = int(input("请输入数字: ")) result = 100 / num print(f"结果是 {result}") except ValueError: print("输入的不是有效数字") except ZeroDivisionError: print("除数不能为0") except Exception as e: # 兜底捕获所有未预料的异常 print(f"发生了未知错误: {e}")

这里Exception是大多数异常的基类,ValueError和ZeroDivisionError是它的子类。except Exception as e是最后的兜底手段,能避免程序直接崩溃退出,同时打印出具体错误信息供排查。不过要注意:不能只写一个except:裸捕获不打印任何信息,那等于把bug吞了,出了问题完全不知道怎么排查。

4.5 更高效的调试工具:从print升级到pdb和IDE断点

当你逐渐熟练,print调试会越来越低效。这时候该学习使用调试器了。Python内置的pdb是命令行调试器,最简单的用法是在代码里插入breakpoint()函数,运行时程序会在这一行自动暂停,进入交互式调试模式,你可以输入p 变量名查看变量值,输入n执行下一行,c继续运行到下一个断点。

如果你用VSCode或PyCharm,那更简单——在行号左侧点一下设置断点,按F5开始调试,鼠标悬停在变量上就能看到值。这两招学完之后,你的代码排错效率会有质的飞跃。调试器和print并不互斥,我现在也是两者结合用的,print用于快速粗筛,断点用于精确定位。

5. 为什么这20个实例值得反复练习

最后我想聊聊学习方法层面的个人体会。很多人手里攒了好几个G的PDF和视频教程,收藏了无数“100例”文章,但真正动手敲过的代码屈指可数。我始终认为,Python这种技能是“手上功夫”,不是“眼睛功夫”,光看永远学不会,必须亲手把代码敲到编辑器里、跑出结果、踩过报错、修好它,才算真正吸收。

我建议的核心练法是这样的:拿到一个经典实例,先不看任何参考答案,自己动手写。写不出来没关系,卡十分钟之后再看答案,看懂之后关掉答案,从头到尾默写一遍。默写完了,再做改动实验,把参数改一改、边界条件换一换、输出格式变一变,观察程序的反应。这个流程走完,一个实例才算真正消化成你自己的东西。

不要追求一天刷完几十例,也不要在基础序列(我上面列的这些)没练透之前就去碰爬虫、Web框架这些“看起来更高级”的方向。系好鞋带才能跑得快,基础的地基打得越扎实,后面学任何方向都会事半功倍。

如果你按这个节奏把前面20个实例全部练完,你会发现自己看代码、调bug、读报错信息的能力都会上一个台阶。那时候,你再回去翻那100例的清单,会惊讶地发现大部分题你已经能秒速看出思路,根本不需要再逐行跟着敲了。这,才是那份“经典实例清单”真正应该带给你的东西。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询