Python基础语法练习题(49-50)

紧接着再来两道题。

第四十九题,随机生成验证码:

复制代码
#编写一个程序,该程序能够根据用户指定的长度生成一个验证码(可包含大小写英文字母以及数字)

#导入模块

import random
import string

#获取用户输入信息

lens = int(input('请输入你想要验证码的长度:'))

#定义验证码中可能包含的字符集(需要导入string模块)

chars = string.digits + string.ascii_letters

verify_code = ''

for i in range(lens):

    verify_code += random.choice(chars)

print(f'本次生成的验证码是:{verify_code}')

代码的思路如下:

我的整体设计:先建"奖池",再"抽奖"

这题我脑子里的模型就是一台抽奖机:先把所有可能被抽中的东西装进一个池子,然后伸手进去摸一把,摸几次就拼出几个字符。拆开来是四步:备字符池 → 问长度 → 循环抽取 → 拼接输出。

第一步:字符池怎么来?------ 让 string 模块替我干活

验证码要"大小写字母加数字",老实人写法是把 a-z、A-Z、0-9 共 62 个字符手敲成一个字符串。但我不想在这种地方费手指,于是导入了 string 模块,它里面正好有现成的常量:

chars = string.digits + string.ascii_letters

string.digits 就是 '0123456789',string.ascii_letters 就是全部大小写字母,一个加号把它们拼成一个大字符串,我的"奖池"就建成了。这也是我第一次体会到:标准库连字符表都替你备好了。

第二步:长度交给用户

int(input(...)) 问出验证码长度。这里我刻意用了 int(),因为 input 拿到的永远是字符串,不转成整数的话,下一步 range(lens) 会直接报错。

第三步:循环抽取 + 字符串拼接(核心)

这是全程序最有趣的三行:

verify_code = ''

for i in range(lens):

verify_code += random.choice(chars)

先准备一个空字符串当"篮子";

random.choice(chars) 就是往池子里摸一把------每次从 62 个字符里随机抓 1 个(这正是对 48 题学的 random 家族的再扩展:random() 管小数、randint() 管整数、choice() 管"从序列里选一个");

+= 把摸到的字符接到篮子尾巴上,循环 lens 次,篮子就攒满了。

这个"先建空变量、循环里不断累加"的套路,其实就是** accumulator(累加器)模式**,只不过上次加的是数字,这次加的是字符串。

第四步:f-string 输出

print(f'本次生成的验证码是:{verify_code}')------f 前缀让变量能直接嵌在字符串里,比用加号拼接干净多了。

和前面题目的思路联系

这题像是 43 题和 48 题的"会师":48 题教我用现成模块搞随机,这题把它用到了真实场景里;43 题教我 int(input()) 转类型,这题继续用它问长度。不过我有个私货反思:43 题可是专门教"输入验证"的,而这题的 int(input(...)) 是裸奔的------用户要是输个 abc 或者负数,程序当场崩溃。写博文时我特意提一嘴:学有余力的朋友可以把这里替换成 43 题那套 while True + try/except,程序会立刻健壮起来。

总结

我的设计一句话概括:字符池交给 string 模块,随机抽取交给 random.choice,我只负责搭那个"循环拼接"的架子。三个零件全是现成的,程序却拼出了很实用的功能------这就是 Python "模块拼装"开发风格的甜头。

顺带预告:下一题"从范围里挑 3 个不重复的数",choice 可做不到不重复(同一奖品可能被摸两次),到时候得再认识一位新成员。

第五十题,从指定范围内选择3个不重复的数字:

复制代码
#编写一个程序,该程序能从用户指定的范围内获取3个随机不重复的数字

#导入模块

import random

#用户指定范围

start = int(input('请输入您所需要的起始区间:'))

end = int(input('请输入您所需要的结束区间:'))

#使用random,sample(population,k)完成需求,这个语句的意思是从population序列中随机选择k个不重复的元素

result = random.sample(range(start,end + 1),3)

print(f'为您选择的3个不重复的随机数字分别是:{result}')

代码的思路如下:

上一题留下的问题,这题解决了

49 题我做验证码时用的是 random.choice(),它每次只摸一个字符,而且是放回去再摸------同一个数字完全可能被抽中两次。可这题的要求偏偏是"不重复",用 choice 就得自己写"抽完查一下重不重要、重来"的麻烦逻辑。

好在我翻文档时找到了 random 家族的又一位成员:random.sample(序列, k)------从序列里一次抓 k 个元素,保证不重复,还不放回。上一题是一球一摸,这一题是伸手进去一把抓三球,正合需求。

我的设计就三步

第一步:问出范围。 两次 int(input(...)),拿到起始值和结束值。和 49 题一样直接转整数,因为后面要用它们构造序列。

第二步:把"范围"变成"名单"(本题最小心机的地方)。

range(start, end + 1)

random.sample 要求你给它一个可以从中挑东西的序列,可用户给的只是一个区间,所以我用 range() 把区间铺成一串整数当"候选名单"。

关键在那个 + 1:range 是左含右不含的,range(1, 10) 只到 9 为止,10 根本不在这份名单上。用户说"结束区间是 10",肯定是想把 10 也纳入抽奖池,所以我必须手动写成 end + 1,让名单正好盖到用户说的末端。大家注意:这已经是 Python 里第三次在"端点含不含"上给我上公开课了(48 题的 random()、randint(),加这回的 range())。

第三步:一句话完成抽取。 random.sample(名单, 3) 返回一个含 3 个不重复数字的列表,比如 7, 2, 9,用 f-string 直接打印收工。

我发现的隐患:这份"名单"可能不够抽

sample 有个硬脾气:如果名单里的元素不足 3 个(比如用户输了 1 到 2),它会直接抛 ValueError 罢工。再加上输入本身也是裸 int(input()),输个字母照样崩。这题的代码赌的是"用户好好输入"------赌赢了顺畅运行,赌输了当场报错。想稳的话,43 题那套 while True + try/except 验证、再加上"区间跨度至少为 3"的检查,正好能补上这个窟窿。

和前面题目的思路联系

这一小题把 random 家族的三位成员用串了:48 题的 random() 和 randint() 教你生成随机数,49 题的 choice() 教你从池子里摸一个(可重复),今天 sample() 教你从池子里摸多个(不可重复)。选哪个,就看你抽的是"一个还是多个"、"要不要放回"。

总结

我的设计一句话:用 range(start, end+1) 把区间铺成名单,再让 random.sample 一把抓走 3 个不重复的。整道题的难度几乎全压在那个小写的 + 1 上------边界问题不处理好,用户指定的"结束区间"就永远抽不到,这个细节请所有新手一定刻进 DNA。

相关推荐
翼辉cto1 小时前
Kotlin Multiplatform 三方库 SQLDelight 的 OpenHarmony 鸿蒙化适配实战
开发语言·kotlin·harmonyos
Cc.Y1 小时前
Java零基础入门:集合框架:ArrayList 与 LinkedList —— 告别数组的“死板“,拥抱动态容器的“灵活
java·开发语言·python
qeen871 小时前
【QT】 信号与槽初始
开发语言·笔记·qt·学习
FYKJ_20101 小时前
springboot游泳馆管理系统79222-计算机课程设计、毕业设计
vue.js·spring boot·后端·python·mysql·django·课程设计
艾莉丝努力练剑2 小时前
【AI大模型接入SDK】C++ ChatSDK使用手册
开发语言·网络·c++·人工智能·学习·大模型
“AI国潮设计-小江”10 小时前
《Python+SDXL实战:用ControlNet精准控制“英歌舞翻糖吐司”构图,附批量生成脚本》
开发语言·人工智能·python·prompt·aigc
程序喵大人10 小时前
【C++入门】编译链接模型 - 01 一个 C++ 程序是怎样变成可执行文件的
开发语言·c++·编译链接模型
wenwen_chao11 小时前
Python学习与开发资源合集:实用技巧与工具推荐
python
for_ever_love__12 小时前
函数——参数、lambda、*args与作用域
python·函数·大模型开发·编程基础