当前位置: 首页 > news >正文

Python的简单练习

两数的最大公约数 

def gcd(a, b):while b != 0:a, b = b, a % breturn a# 示例
a = 36
b = 60
print(f"{a} 和 {b} 的最大公约数是: {gcd(a, b)}")

while b != 0:

  • while:是 Python 的 循环语句,意思是“当...的时候一直重复做某事”。

  • b != 0:表示“只要 b 不等于 0”,就继续执行下面的代码。

对角线相连的菱形

n = int(input("请输入菱形的边长:"))# 上半部分(含中间行)
for i in range(n):for j in range(2 * n - 1):if j == n - 1 - i or j == n - 1 + i:print("*", end="")else:print(" ", end="")print()# 下半部分(不含中间行)
for i in range(n - 2, -1, -1):for j in range(2 * n - 1):if j == n - 1 - i or j == n - 1 + i:print("*", end="")else:print(" ", end="")print()

if j == n - 1 - i or j == n - 1 + i

print()直接换行

杨辉三角

def generate_yanghui_triangle(n):triangle = []  # 存储整个三角形for i in range(n):row = [1] * (i + 1)  # 每一行最开始全是 1# 从第二个元素到倒数第二个元素开始计算for j in range(1, i):row[j] = triangle[i - 1][j - 1] + triangle[i - 1][j]triangle.append(row)return triangle# 显示杨辉三角
def print_triangle(triangle):n = len(triangle)for i, row in enumerate(triangle):print(" " * (n - i), end="")  # 打印前导空格对齐for num in row:print(f"{num} ", end="")print()# 示例
rows = int(input("请输入杨辉三角的行数:"))
triangle = generate_yanghui_triangle(rows)
print_triangle(triangle)

triangle 实际上是一个:列表的列表

[
 [1],
 [1, 1],
 [1, 2, 1],
 [1, 3, 3, 1],
 ...
]
 

Python 不会主动去判断变量类型,也不要求变量的结构一定一致

只是遍历 triangle 这个变量。只要这个变量“像个列表”,能被遍历就行

len(triangle) 是获取 triangle 的行数

for i, row in enumerate(triangle):一边遍历列表,一边记录当前的“行号” i 和当前的“行内容” row

print(" " * (n - i), end="")让数字靠近中轴线

def func():
print("hello")
这个会报错,因为没有缩进。

def func():
    print("hello", end="")  # 不换行
    print("world")
这个没问题,虽然不换行,但语法结构没错,因为语句都在 def 下面、缩进对齐。

统计不同字符(字母、数字、空格、其他字符)的个数

text = input("请输入一段文本:")letters = 0
digits = 0
spaces = 0
others = 0for ch in text:if ch.isalpha():       # 字母letters += 1elif ch.isdigit():     # 数字digits += 1elif ch.isspace():     # 空格spaces += 1else:                  # 其他字符others += 1print(f"字母: {letters} 个")
print(f"数字: {digits} 个")
print(f"空格: {spaces} 个")
print(f"其他字符: {others} 个")

检查字符串包含

text = "Life is short.I use python"if "python" in text:new_text = text.replace("python", "Python")print("替换后的字符串:", new_text)
else:print("原字符串:", text)

随机生成六位验证码

random模块

---randint(0,9)可生成一个0-9之间的随机整数

---random.choice()从参数中选择一个

string模块

---string.ascii_letters可得到所有字母

---string.digits可得到所有数字

import random
import stringdef generate_code(length=6):chars = string.ascii_letters + string.digits  # 所有字母 + 数字code = ''.join(random.choice(chars) for _ in range(length))return code# 示例
print("生成的验证码是:", generate_code())

random.choice(chars) for _ in range(length), 生成器表达式(generator expression)

''.join(...) 会把生成器里的字符连成一个字符串

code = ''
for _ in range(6):
    code += random.choice(chars)也可以但是 .join() + 生成器写法更快、更优雅。

进度条

进度条一般以图形的方式显示已完成任务量和未完成任务量,并以动态文字的方式显示任务的完成度。要求编写程序实现文本进度条功能。

import timedef progress_bar(total=30):for i in range(total + 1):percent = int((i / total) * 100)bar = '#' * i + '-' * (total - i)print(f"\r[{bar}] {percent}%", end="")time.sleep(0.1)  # 模拟加载过程print("\n任务完成!")# 示例
progress_bar()

total 表示 进度条的总长度,

i / total → 得到当前进度(比如 0.5),* 100 → 换算成百分比

\r → 回到行首,刷新当前行,end="" 避免换行,sleep() 控制速度

过滤敏感词

编写代码,实现具有过滤敏感词功能的程序。

def filter_sensitive(text, sensitive_words):for word in sensitive_words:if word in text:text = text.replace(word, "*" * len(word))return text# 示例
sensitive_list = ["暴力", "不健康", "sb", "傻瓜"]
user_input = input("请输入一段话:")filtered = filter_sensitive(user_input, sensitive_list)
print("过滤后的结果:", filtered)

将字符串的每一个字符放入列表中

text = "hello"
char_list = list(text)
print(char_list)

列表去重

li_one = [1, 2, 1, 2, 3, 5, 4, 3, 5, 7, 4, 7, 8]# 使用集合去重,再转回列表(注意顺序会改变)
li_one_unique = list(set(li_one))print("去重后的列表:", li_one_unique)

set(li_one)

  • set 是 Python 中的集合类型,它的特点是:

    • 不允许重复元素

    • 元素无序

list(...)

  • 因为集合类型 set 不是列表,如果你想继续像操作列表那样使用它(比如排序、索引等),就需要转回列表类型。

  • 所以用 list(set(li_one)) 就把“去重后的集合”变成了一个新列表。

由于集合 set无序的,所以转换之后的新列表 li_one_unique 的元素顺序通常会和原来 li_one 中的顺序不一致

列表合并降序排列

li_num1 = [5, 5, 2, 7]
li_num2 = [3, 6]# 合并
merged_list = li_num1 + li_num2# 降序排序
sorted_desc = sorted(merged_list, reverse=True)print("合并后并降序排序的列表:", sorted_desc)

sorted() 是 Python 的一个内置函数,用于对任何可迭代对象进行排序(比如列表、元组、集合等)。

返回的是一个新的已排序列表,不会修改原来的 merged_list

  • reversesorted() 的一个可选参数

  • 当你设置 reverse=True 时,表示按照降序来排列元素。

  • 如果是默认的 reverse=False,就是升序排列

8名教师随机分配办公室

import random# 老师名单
teachers = ['孙老师', '吴老师', '王老师', '钱老师', '李老师', '周老师', '赵老师', '郑老师']# 办公室,初始化为空列表
offices = [[], [], []]# 打乱老师顺序(确保分配随机性)
random.shuffle(teachers)# 分配老师:前3个给办公室1,接着3个给办公室2,剩下2个给办公室3
offices[0] = teachers[:3]
offices[1] = teachers[3:6]
offices[2] = teachers[6:]# 打印分配结果
for i, office in enumerate(offices, 1):print(f"办公室{i}的人数是{len(office)}. 老师分别是:{', '.join(office)}")

enumerate(offices, 1) 会遍历每一个办公室列表,并同时给它一个“编号”:

第一次循环i = 1, office = ['孙老师', '吴老师', '王老师']
第二次循环i = 2, office = ['钱老师', '李老师', '周老师']
第三次循环i = 3, office = ['赵老师', '郑老师']

enumerate(..., 1)1 是指定从1开始编号(默认是从0开始的)。

len(office) 就是这个办公室里老师的数量

join() 是一个字符串方法,用来把一个列表里的字符串连接成一个字符串,中间用逗号隔开。

office = ['孙老师', '吴老师', '王老师']
', '.join(office)  → '孙老师, 吴老师, 王老师'

十大歌手评选

votes = {}  # 用于记录每个歌手的得票数print("请输入你要投票的歌手名字(输入 'end' 结束):")while True:name = input("投票给:")if name.lower() == 'end':breakvotes[name] = votes.get(name, 0) + 1# 排序输出:按票数从高到低
sorted_votes = sorted(votes.items(), key=lambda x: x[1], reverse=True)print("\n投票结果:")
for singer, count in sorted_votes:print(f"{singer}: {count}票")

votes[name] = votes.get(name, 0) + 1

作用:每投一次票,票数加1。
这行是给歌手(或候选人)计票用的。

  • votes 是一个字典,记录每个人的票数:
    例如:{'张三': 2, '李四': 3}

  • votes.get(name, 0) 的意思是:

    • 去字典里找名字为 name 的那个人的票数;

    • 如果还没出现过(字典里没有这个名字),就返回 0

    • 相当于默认票数是0。

  • 然后 +1:当前票数加一。

  • 最终更新写入字典:

    • 如果是新的人,就新加进去;

    • 如果已经有了,就在原来的基础上加1。

sorted_votes = sorted(votes.items(), key=lambda x: x[1], reverse=True)

作用:把投票结果按票数从高到低排序

  • votes.items():把字典转换成一个列表,每一项是 (名字, 票数) 这样的元组:

    {'张三': 3, '李四': 1}.items() → [('张三', 3), ('李四', 1)]

  • sorted(..., key=lambda x: x[1])
    排序的时候按照元组的第2个元素(也就是票数)来比较。

    lambda x: x[1] 是匿名函数,意思是“拿到每个 (名字, 票数) 元组的 票数”。

  • reverse=True:表示降序排列(票数多的排前面)。

分类统计字符个数

编写程序,用户输入一个字符串,以回车结束,利用字典统计其中字母和数字出现的次数(回车符代表结束)。

输入格式是一个以回车结束的字符串,例如输入abc1ab,输出{'a': 2, 'b': 2, 'c': 1, '1': 1}。

text = input("请输入一个字符串(回车结束):")
counter = {}for char in text:if char.isalnum():  # 判断是否是字母或数字counter[char] = counter.get(char, 0) + 1print(counter)

计票机制(类歌手)

candidates = ['张三', '李四', '王五']
votes = dict.fromkeys(candidates, 0)print("候选人有:", ', '.join(candidates))
print("请输入投票人名(输入 'end' 结束):")while True:name = input("投票给:")if name.lower() == 'end':breakif name in votes:votes[name] += 1else:print("无效候选人,票数不计。")# 输出最终结果
sorted_votes = sorted(votes.items(), key=lambda x: x[1], reverse=True)print("\n计票结果:")
for person, count in sorted_votes:print(f"{person}: {count}票")

votes = dict.fromkeys(candidates, 0)

作用:根据候选人列表创建一个初始“投票字典”,每个人的票数都设为 0。

candidates = ['张三', '李四', '王五']

votes = dict.fromkeys(candidates, 0) # 得到

votes = {'张三': 0, '李四': 0, '王五': 0}

name.lower()

作用:把用户输入的名字全部转成小写,通常用于不区分大小写的匹配判断。

sorted_votes = sorted(votes.items(), key=lambda x: x[1], reverse=True)

这就是你前面问过的:

  • 按照**票数(x[1])**进行排序;

  • reverse=True 表示 降序(票数多的排在前面);

  • 结果是一个列表,元素是元组 (名字, 票数)

斗地主发牌看牌

(要求看牌时排序展示)

import random  # 导入随机模块,用于洗牌# 定义花色(suits)和点数(ranks)
suits = ['♠', '♥', '♣', '♦']   # 黑桃、红桃、梅花、方块
ranks = ['3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A', '2']  # 常规牌面# 生成一副完整的扑克牌(不包括大小王的52张 + 小王 + 大王)
deck = [s + r for r in ranks for s in suits] + ['小王', '大王']# 洗牌:打乱deck中的顺序
random.shuffle(deck)# 创建三个玩家的牌堆 + 1个底牌堆
player1 = []
player2 = []
player3 = []
bottom = []# 发牌(共54张,前51张发给三位玩家,最后3张作为底牌)
for i in range(len(deck)):if i < 51:if i % 3 == 0:player1.append(deck[i])  # 玩家1每隔3张拿一张elif i % 3 == 1:player2.append(deck[i])  # 玩家2每隔3张拿一张else:player3.append(deck[i])  # 玩家3每隔3张拿一张else:bottom.append(deck[i])  # 剩下3张作为底牌# 定义一个排序函数:将玩家手牌按点数大小排序
def sort_cards(cards):# 创建一个牌面优先级映射(数字越大表示牌越大)order = {r: i for i, r in enumerate(ranks)}  # 3最小,2最大(不含王)order.update({'小王': 13.5, '大王': 14})      # 王的等级高于所有普通牌# 自定义排序函数:提取每张牌的“点数”部分用于比较def card_key(card):if card in ['小王', '大王']:return order[card]  # 王直接用其键值return order[card[1:]]  # 从第2位开始取(排除花色)# 返回按牌面大小排序后的牌列表return sorted(cards, key=card_key)# 输出发牌结果,并按点数顺序展示每位玩家的手牌
print("\n=== 发牌结果 ===")
print("玩家1:", sort_cards(player1))
print("玩家2:", sort_cards(player2))
print("玩家3:", sort_cards(player3))
print("底牌:", sort_cards(bottom))

deck = [s + r for r in ranks for s in suits]
花色在前,点数在后的生成方式,比如 ♠3, ♥3, ♣3, ♦3, ♠4, ...
如果你想让点数排在前(比如 3♠),只需调换一下顺序。

for i in range(len(deck)):

deck = ['♠3', '♥4', ..., '小王', '大王']

相对于for i in range(54):  # i 依次是 0, 1, 2, ..., 53

  • i < 51:表示前 51 张是正常发给玩家的;

  • i >= 51:表示最后 3 张是底牌。

然后再通过 i % 3 来轮流分给 3 个玩家。

order = {r: i for i, r in enumerate(ranks)}
这行用的是字典推导式,将点数与大小关系建立起来。

enumerate(ranks) 会返回每个点数及其位置编号:

ranks = ['3', '4', '5', ..., '2']
→ [('3', 0), ('4', 1), ..., ('2', 12)]

所以构造出的字典是: 

order = {'3': 0, '4': 1, '5': 2, '6': 3, '7': 4,'8': 5, '9': 6, '10': 7, 'J': 8, 'Q': 9,'K': 10, 'A': 11, '2': 12
}

order.update({'小王': 13.5, '大王': 14})
这行的意思是:往 order 字典中再加两个键值对:比“2”还大,用来确保在排序时,“王”排到最上面。



def card_key(card):
        if card in ['小王', '大王']:
            return order[card] 
        return order[card[1:]] 

    return sorted(cards, key=card_key)

我们之前建立了一个排序规则 order,用于表示每张牌的大小关系:

order = {'3': 0, '4': 1, ..., '2': 12,'小王': 13.5, '大王': 14
}

现在你有一手牌,比如:

cards = ['♠3', '♦A', '小王', '♥10', '♣2']

def card_key(card):  定义一个排序时的“取键函数”
在 Python 的 sorted(..., key=...) 中,我们可以自定义用什么“值”来排序 —— 这里我们自定义的函数名是 card_key

if card in ['小王', '大王']: return order[card]

- 如果这张牌是 `'小王'` 或 `'大王'`,那就直接返回 `order` 中对应的数值(13.5 或 14)用于排序。

  • 如果不是王,那就说明是正常的扑克牌,比如 '♠3''♥10' 等。

  • card[1:] 表示从索引1开始切取,也就是去掉前面的花色符号,只保留点数

原始牌card[1:]排序用值 (order[card[1:]])
'♠3''3'0
'♦A''A'11
'♥10''10'7

这样我们就可以用这些数值去比较牌的大小了。

return sorted(cards, key=card_key)

  • sorted(...) 是 Python 内置的排序函数,会返回一个新的列表。

  • key=card_key 指定了“按照什么规则排序”,也就是我们自定义的 card_key 函数。

  • 这样就能确保牌是按照 order 字典定义的大小顺序排列的。

为什么要用 card[1:] 而不是正则或者其他方式提取点数?

点数部分可能是 '10''J''Q',所以不能只取一个字符,要用切片取后面所有字符 → card[1:]

编写函数完成角谷猜想

模拟和验证一个著名数学问题——角谷猜想(也叫冰雹猜想,英文叫 Hailstone conjectureCollatz Conjecture)。

对于任意一个正整数 n,重复以下操作:

  • 如果 n 是偶数:把 n 变成 n / 2

  • 如果 n 是奇数:把 n 变成 3n + 1
    重复这个过程,最终总会变成 1

def hailstone_sequence(n):steps = [n]                # 记录整个序列(从 n 开始)while n != 1:              # 不断重复直到 n 变成 1if n % 2 == 0:n = n // 2         # 偶数除以2else:n = n * 3 + 1      # 奇数乘3加1steps.append(n)        # 每次结果加入列表return steps               # 返回完整路径

饮品自动售货机

def vending_machine():menu = {'1': ('可乐', 3),'2': ('绿茶', 2.5),'3': ('矿泉水', 2)}print("欢迎使用自动售货机:")for k, v in menu.items():print(f"{k}: {v[0]} - ¥{v[1]}")choice = input("请输入你要购买的饮品编号:")if choice not in menu:print("无效选择")returndrink, price = menu[choice]money = float(input(f"请投币(需要 ¥{price}):"))if money >= price:change = money - priceprint(f"你购买了 {drink},找零 ¥{change:.2f}")else:print("金额不足,交易取消")# 示例调用
vending_machine()

学生管理系统

students = []def add_student(name, age):students.append({'name': name, 'age': age})print(f"添加成功:{name}, 年龄{age}")def show_students():print("当前学生列表:")for s in students:print(f"{s['name']}({s['age']}岁)")# 示例
add_student('小明', 18)
add_student('小红', 17)
show_students()

两个数的最大公约数与最小公倍数

def gcd(a, b):while b:a, b = b, a % breturn adef lcm(a, b):return a * b // gcd(a, b)# 示例
print("最大公约数:", gcd(24, 36))
print("最小公倍数:", lcm(24, 36))

登录验证(次数限制)

def login_system():attempts = 0while attempts < 5:username = input("用户名:")password = input("密码:")if username == 'admin' and password == 'admin123':print("登录成功")returnelse:attempts += 1print(f"请重新登录(还剩 {5 - attempts} 次)")print("账户已被锁定,请联系管理员解锁")login_system()

登录验证装饰器 + 系统操作函数

# 模拟登录状态
login_status = {"logged_in": False}# 登录验证装饰器
def require_login(func):def wrapper(*args, **kwargs):if not login_status["logged_in"]:username = input("用户名:")password = input("密码:")if username == "admin" and password == "admin123":login_status["logged_in"] = Trueprint("✅ 登录成功")else:print("❌ 登录失败,无法操作")returnreturn func(*args, **kwargs)return wrapper# 系统功能函数
@require_login
def add_data():print("数据添加成功")@require_login
def delete_data():print("数据删除成功")@require_login
def update_data():print("数据更新成功")# 测试
add_data()     # 第一次需登录
delete_data()  # 已登录,无需再输密码

什么是 @require_login

Python 的一个语法糖,叫做:函数装饰器(Decorator)

它的作用是:在不修改原函数代码的情况下,为函数增加额外的功能

@require_login
def add_data():
    print("数据添加成功")

等价于:add_data = require_login(add_data)

也就是说,add_data 这个函数被 require_login 装饰后,变成了它返回的 wrapper 函数。

把装饰器 给函数套了个“壳子”

@xxx 本质上就是:把当前函数交给 xxx() 来加工

def require_login(func):def wrapper(*args, **kwargs):# 做登录验证return func(*args, **kwargs)  # 如果验证通过,再运行原函数return wrapper

这段代码的意思其实是:

✨“我定义了一个叫 require_login函数工厂,它接受一个函数 func,然后给它包一层登录验证功能,最后返回这个‘增强后的函数’。”✨

第一级函数:require_login(func)

这是 你定义的装饰器函数本体。它接收另一个函数作为参数——就是你想“加功能”的那个函数(比如 add_data())。

它的作用就是返回一个新函数wrapper

第二级函数:wrapper(*args, **kwargs)

这是你创建的“壳函数”,负责:

  1. 先判断登录状态

  2. 如果未登录就提示并要求输入用户名密码

  3. 如果登录成功,再执行原函数 func(...)

它就像是在你真正的 add_data()delete_data() 等函数 外面套的一层保护壳

为什么要返回 wrapper 而不是直接运行它?

因为你希望是“以后再用的时候”才执行验证,不是定义的时候就立即执行。

@require_login
def add_data():
    ...
这时只是把 add_data 换成了新的 wrapper 函数(它内部包含了登录判断 + 原始 add_data),还没有真正执行它

这段代码是典型的:

“高阶函数 + 闭包结构”

  • 高阶函数:函数接收函数作为参数,或返回函数

  • 闭包:wrapper() 内部访问了 func,形成了“带记忆”的函数

写法意义
*args接收任意数量的位置参数(变成一个元组)
**kwargs接收任意数量的关键字参数(变成一个字典)

用法场景原因
写装饰器你不知道被包装的函数参数数量和类型
写通用函数比如日志函数、统计函数,参数可变
接收动态传参比如配置字典、自动调用接口

递归求和函数 f(n)

def f(n):if n == 1:return 1return n + f(n - 1)# 示例
print(f(10))  # 输出 55

找出所有既是回文数又是素数的 3 位数

def is_palindrome(n):return str(n) == str(n)[::-1]def is_prime(n):if n < 2:return Falsefor i in range(2, int(n**0.5) + 1):if n % i == 0:return Falsereturn Truedef find_palindromic_primes():result = []for n in range(100, 1000):if is_palindrome(n) and is_prime(n):result.append(n)return resultprint(find_palindromic_primes())
 for i in range(2, int(n**0.5) + 1):if n % i == 0:return False

2√n(包含)逐一检查是否能整除 n,如果能整除,就不是素数。

**是根号

  • 在 Python 中,** 表示 幂运算(power)

  • 所以 n**0.5 就等于 n 的 0.5 次方

  • n 的 0.5 次方,数学上就是 √n

确保从 2 检查到 3,完整覆盖了素数判断所需范围。

range(2, 3+1) → [2, 3)

range(start, end) 的含义:

参数含义
start起始值(包含)
end终止值(不包含

模拟轮盘抽奖函数

import randomdef spin_wheel():r = random.random()  # 生成 [0.0, 1.0) 的浮点数if 0 <= r < 0.08:return "🎉 恭喜你抽中一等奖!"elif 0.08 <= r < 0.3:return "🎊 恭喜你抽中二等奖!"else:return "✨ 抽中三等奖,继续加油!"# 测试多次抽奖
for _ in range(5):print(spin_wheel())

保存到你运行脚本时所在的目录下,文件名是你传入的那个 json_path

技能类型涉及模块/函数
文件复制shutil.copy()
字符操作.swapcase()
文件读写open(..., "r/w")
CSV 写入/读取csv.writer / csv.DictReader
JSON 存取json.dump() / json.load()
条件循环与判断whileif

相关文章:

  • Python硬核革命:从微控制器到FPGA的深度开发指南
  • 降维大合集
  • 前端面经-VUE3篇(二)--vue3组件知识(一)组件注册、props 与 emits、透传、插槽(Slot)
  • LeetCode240. 搜索二维矩阵 II(巧妙转换)
  • Leetcode刷题记录29——矩阵置零
  • 高维亚空间超频物质变压缩技术 第27次CCF-CSP计算机软件能力认证
  • 力扣:24两两交换链表的节点
  • 融智学16字方针无歧义表述并构建人机协同的非零和博弈模型
  • SVM实战:从理论到鸢尾花数据集的分类可视化
  • Android 端如何监控 ANR、Crash、OOM 等严重问题
  • 基于SpringBoot+Vue实现的电影推荐平台功能三
  • Oracle OCP认证考试考点详解083系列04
  • ip和域名
  • hadoop存储数据文件原理
  • 大数据Spark(五十八):Spark Pi介绍
  • 49-dify案例分享-私有化 MCP 广场搭建与网页小游戏智能体工作流实战
  • 【Bootstrap V4系列】学习入门教程之 组件-徽章(Badge)和面包屑导航(Breadcrumb)
  • C++ 开发指针问题:E0158 表达式必须为左值或函数指示符
  • 【React】Hooks useReducer 详解,让状态管理更可预测、更高效
  • ActiveMQ 集群搭建与高可用方案设计(一)
  • 台湾花莲县海域发生5.7级地震,震源深度15公里
  • 探访小剧场、直播间、夜经济:五一假期多地主官调研新消费
  • 山大齐鲁医院护士论文现“男性确诊子宫肌瘤”,院方称将核实
  • 徐丹任武汉大学药学院院长:研究领域在国际上处领跑地位
  • 德国旅游胜地发生爆炸事故,11人受伤
  • 北部艳阳高照、南部下冰雹,五一长假首日上海天气很“热闹”