
题目考点
这道题主要考的是 字符串遍历 和 字符串判断方法。
核心知识点有:
| 方法 | 作用 |
|---|---|
c.isalnum() | 判断字符 c 是否是字母或数字 |
c.isalpha() | 判断字符 c 是否是字母 |
c.isdigit() | 判断字符 c 是否是数字 |
c.islower() | 判断字符 c 是否是小写字母 |
c.isupper() | 判断字符 c 是否是大写字母 |
这题的重点不是统计有多少个,而是判断:字符串里有没有至少一个符合条件的字符。
一、审题
题目给你一个字符串 S。
你需要分别判断这个字符串中是否包含:
- 字母或数字
- 字母
- 数字
- 小写字母
- 大写字母
然后依次输出 5 行,每一行输出 True 或 False。
比如样例输入:
qA2
我们逐个看:
| 字符 | 是字母或数字 | 是字母 | 是数字 | 是小写 | 是大写 |
|---|---|---|---|---|---|
q | 是 | 是 | 否 | 是 | 否 |
A | 是 | 是 | 否 | 否 | 是 |
2 | 是 | 否 | 是 | 否 | 否 |
所以结果是:
True
True
True
True
True
二、思路提示
这道题可以这样想:
题目要我们判断 5 件事,每件事都是:
字符串里是否存在至少一个字符满足某个条件?
比如第一问:
字符串里有没有至少一个字符是字母或数字?
那我们就可以遍历字符串里的每个字符:
for c in s:
判断 c 是不是字母或数字
只要发现有一个字符符合条件,就可以说明结果是 True。
Python 中有一个非常适合这类题的函数:any()。
它的意思是:
只要里面有一个条件成立,结果就是
True;如果全部不成立,结果才是False。
比如:
any(c.isdigit() for c in s)
意思是:
遍历字符串
s中的每个字符c,只要有一个c是数字,整体结果就是True。
三、完整设计思路
这道题可以拆成 3 步。
第一步:读取字符串
s = input()
这里的 input() 会读取一整行输入,得到的是字符串。
第二步:分别判断 5 种情况
对应题目的 5 行输出,我们分别写 5 个判断:
any(c.isalnum() for c in s)
any(c.isalpha() for c in s)
any(c.isdigit() for c in s)
any(c.islower() for c in s)
any(c.isupper() for c in s)
它们分别表示:
| 代码 | 含义 |
|---|---|
any(c.isalnum() for c in s) | 是否存在字母或数字 |
any(c.isalpha() for c in s) | 是否存在字母 |
any(c.isdigit() for c in s) | 是否存在数字 |
any(c.islower() for c in s) | 是否存在小写字母 |
any(c.isupper() for c in s) | 是否存在大写字母 |
第三步:按顺序打印结果
题目要求输出 5 行,所以每个判断单独 print() 一次。
四、代码实现
s = input()
print(any(c.isalnum() for c in s))
print(any(c.isalpha() for c in s))
print(any(c.isdigit() for c in s))
print(any(c.islower() for c in s))
print(any(c.isupper() for c in s))
这就是这道题最常见、最简洁的写法。
五、代码逐行解释
先看第一句:
s = input()
这句代码读取输入字符串,比如用户输入:
qA2
那么:
s = "qA2"
然后看第一行判断:
print(any(c.isalnum() for c in s))
它会依次检查:
'q'.isalnum()
'A'.isalnum()
'2'.isalnum()
只要有一个是 True,any() 的结果就是 True。
因为 q、A、2 都是字母或数字,所以第一行输出:
True
第二行:
print(any(c.isalpha() for c in s))
检查字符串里有没有字母。
q 和 A 都是字母,所以输出:
True
第三行:
print(any(c.isdigit() for c in s))
检查字符串里有没有数字。
2 是数字,所以输出:
True
第四行:
print(any(c.islower() for c in s))
检查字符串里有没有小写字母。
q 是小写字母,所以输出:
True
第五行:
print(any(c.isupper() for c in s))
检查字符串里有没有大写字母。
A 是大写字母,所以输出:
True
最终输出:
True
True
True
True
True
六、如果不用 any(),可以怎么写?
如果你觉得 any() 一开始不好理解,可以先用普通循环写。
例如判断是否有数字,可以这样写:
has_digit = False
for c in s:
if c.isdigit():
has_digit = True
print(has_digit)
意思是:
一开始假设没有数字:
has_digit = False
然后遍历字符串。
如果遇到数字,就把它改成:
has_digit = True
最后打印结果。
但是这道题要判断 5 种情况,如果全部这样写,代码会比较长。所以更推荐用 any()。
七、方法总结
以后遇到这类题,可以按照这个思路判断:
只要题目出现:
判断字符串中是否包含某种字符
比如:
- 是否包含数字
- 是否包含字母
- 是否包含大写字母
- 是否包含小写字母
- 是否包含特殊符号
就可以想到这个结构:
any(判断条件 for 字符 in 字符串)
本题的固定模板就是:
any(c.某个判断方法() for c in s)
这类题的关键不是复杂算法,而是会不会把题目要求翻译成对应的字符串方法。
八、练习
给你一个字符串 s,判断它是否包含至少一个空格字符。
要求:
如果包含空格,输出 True;否则输出 False。
例如输入:
hello world
输出:
True
提示:
可以遍历字符串中的每个字符,判断:
c == " "
先回答两个问题
这道题目,是采用了函数来解决这样的问题,但是为什么有的题目它是通过比较ascll码来解决这样的问题?而且我也没有看到这道题目,它引用了哪些库或包呀?
这道题确实是用了一些“函数/方法”来解决,比如:
c.isalnum()
c.isalpha()
c.isdigit()
c.islower()
c.isupper()
但是它没有引用任何库或包,因为这些方法是 Python 字符串对象自带的功能。
也就是说,只要 c 是一个字符串字符,就天然可以使用这些方法,不需要写:
import ...
例如:
c = "A"
print(c.isupper())
可以直接运行,因为 isupper() 是字符串类型 str 自带的方法。
一、为什么这道题不用导入库?
Python 里有些功能需要导入库,比如:
import math
然后才能使用:
math.sqrt(16)
但是字符串本身就有很多内置方法,例如:
"abc".isalpha()
"123".isdigit()
"A".isupper()
"a".islower()
这些都属于字符串对象 str 自带的方法。
所以这道题不需要任何导入。
可以这样理解:
c.isdigit()
不是调用外部库,而是在问字符 c:
你自己是不是数字?
二、为什么有的题会比较 ASCII 码?
有些题不用 isdigit()、isalpha() 这些方法,而是通过 ASCII 码范围来判断字符类型。
比如判断一个字符是不是小写字母,可以写:
'a' <= c <= 'z'
或者写成 ASCII 码形式:
97 <= ord(c) <= 122
这里的 ord(c) 可以把字符转成对应的 ASCII 编码值。
例如:
print(ord('a')) # 97
print(ord('z')) # 122
print(ord('A')) # 65
print(ord('Z')) # 90
print(ord('0')) # 48
print(ord('9')) # 57
所以:
| 字符范围 | ASCII 范围 |
|---|---|
'0' 到 '9' | 48 到 57 |
'A' 到 'Z' | 65 到 90 |
'a' 到 'z' | 97 到 122 |
因此,判断数字可以写成:
'0' <= c <= '9'
或者:
48 <= ord(c) <= 57
判断大写字母可以写成:
'A' <= c <= 'Z'
判断小写字母可以写成:
'a' <= c <= 'z'
三、字符串方法和 ASCII 比较有什么区别?
对于初学者来说,先记住一句话:
能用字符串方法时,优先用字符串方法;题目要求你练底层判断时,再用 ASCII 比较。
比如这道题,题目本身就是 HackerRank 的字符串验证题,它的目的就是让你熟悉这些字符串判断方法:
isalnum()
isalpha()
isdigit()
islower()
isupper()
所以用这些方法最合适。
而 ASCII 比较更像是“手动实现判断规则”。
写法一:使用字符串方法
c.isdigit()
意思很直接:
判断
c是不是数字。
写法二:使用字符范围比较
'0' <= c <= '9'
意思是:
判断
c是否落在字符'0'到'9'之间。
写法三:使用 ASCII 编码比较
48 <= ord(c) <= 57
意思是:
先把字符转成编码值,再判断它是否在数字字符的编码范围内。
这三种写法,本质上都是在判断“是不是数字”,只是抽象程度不同。
四、这道题为什么推荐用字符串方法?
因为题目要求分别判断:
- 是否有字母或数字
- 是否有字母
- 是否有数字
- 是否有小写字母
- 是否有大写字母
Python 已经把这些判断封装好了:
| 题目要求 | 推荐方法 |
|---|---|
| 字母或数字 | isalnum() |
| 字母 | isalpha() |
| 数字 | isdigit() |
| 小写字母 | islower() |
| 大写字母 | isupper() |
所以直接写:
print(any(c.isalnum() for c in s))
print(any(c.isalpha() for c in s))
print(any(c.isdigit() for c in s))
print(any(c.islower() for c in s))
print(any(c.isupper() for c in s))
这是最贴合题意的做法。
五、如果用 ASCII 思路,这道题可以怎么写?
你也可以完全不用这些字符串方法,改成 ASCII 范围判断。
先定义几个判断条件:
s = input()
has_alnum = False
has_alpha = False
has_digit = False
has_lower = False
has_upper = False
for c in s:
if '0' <= c <= '9':
has_digit = True
has_alnum = True
if 'a' <= c <= 'z':
has_lower = True
has_alpha = True
has_alnum = True
if 'A' <= c <= 'Z':
has_upper = True
has_alpha = True
has_alnum = True
print(has_alnum)
print(has_alpha)
print(has_digit)
print(has_lower)
print(has_upper)
这段代码的逻辑是:
遇到数字,就说明:
has_digit = True
has_alnum = True
遇到小写字母,就说明:
has_lower = True
has_alpha = True
has_alnum = True
遇到大写字母,就说明:
has_upper = True
has_alpha = True
has_alnum = True
因为字母和数字都属于 alnum,所以只要遇到字母或数字,has_alnum 就应该变成 True。
六、两种写法怎么选择?
可以这样判断:
| 情况 | 推荐写法 |
|---|---|
| 题目考 Python 字符串方法 | 用 isdigit()、isalpha() 等 |
| 题目明确要求判断 ASCII 范围 | 用 'a' <= c <= 'z' 或 ord(c) |
| 想让代码更短、更清晰 | 用字符串方法 |
| 想练底层字符编码 | 用 ASCII 比较 |
| 初学阶段做常规题 | 优先用字符串方法 |
所以这道题最推荐的写法还是:
s = input()
print(any(c.isalnum() for c in s))
print(any(c.isalpha() for c in s))
print(any(c.isdigit() for c in s))
print(any(c.islower() for c in s))
print(any(c.isupper() for c in s))
因为它刚好对应题目要考的字符串验证方法。
七、方法总结
这类题有两条路线。
第一条路线是“调用现成方法”:
c.isdigit()
c.isalpha()
c.isupper()
这种写法更简单,也更符合 Python 的习惯。
第二条路线是“自己判断字符范围”:
'0' <= c <= '9'
'a' <= c <= 'z'
'A' <= c <= 'Z'
这种写法更接近底层原理。
你现在作为初学者,可以先掌握第一种。等你理解了字符本质上也可以比较大小之后,再看第二种就会更容易。
八、练习
给你一个字符串 s,判断它是否包含至少一个英文小写字母。
要求你分别用两种方式思考:
第一种方式:使用字符串方法。
提示:
c.islower()
第二种方式:使用字符范围比较。
提示:
'a' <= c <= 'z'
你可以先试着写出这两种版本。



