Python 练习讲解 · 02 / 25

字符串:统计字符类别与频次

一行文字也是一个字符序列,可以逐个检查、计数和输出。

要学习的知识点

题目

练习 2:统计字符串中的英文字母、数字、空格及字符频次。

输入一行字符串;输出字符频次时用 repr 显示空格等字符。

参考程序:ex02.py;空白练习:lx02.py。

完整代码

以下内容与 ex02.py 一致,可对照右侧讲解阅读。

"""练习 2:统计字符串中的英文字母、数字、空格及字符频次。
输入一行字符串;输出字符频次时用 repr 显示空格等字符。

学习说明:
- input() 读取一整行文本;for 循环每次取出一个字符。
- 通过 if 判断分别统计 ASCII 英文字母、数字和普通空格。
- 用字典保存字符和次数;先判断字符是否已经在字典中,再增加次数。
- repr(ch) 会把空格显示成可辨认的形式。
"""
text = input()

letters = 0
digits = 0
spaces = 0
char_counts = {}

for ch in text:
    if ch.isascii():
        if ch.isalpha():
            letters = letters + 1
        if ch.isdigit():
            digits = digits + 1

    if ch == " ":
        spaces = spaces + 1

    if ch in char_counts:
        char_counts[ch] = char_counts[ch] + 1
    else:
        char_counts[ch] = 1

print("letters:", letters)
print("digits:", digits)
print("spaces:", spaces)
print("frequencies:")
for ch in char_counts:
    count = char_counts[ch]
    print(repr(ch), count)

进阶写法

这版与初学版解决同一道题,写法更精炼。先读代码,再看下面的简要说明。

进阶源码文件:ex02_adv.py

"""练习 2 进阶版:用生成器表达式和字典构造压缩统计步骤。"""
text = input()

letters = sum(ch.isascii() and ch.isalpha() for ch in text)
digits = sum(ch.isascii() and ch.isdigit() for ch in text)
spaces = text.count(" ")
char_counts = {ch: text.count(ch) for ch in dict.fromkeys(text)}

print("letters:", letters)
print("digits:", digits)
print("spaces:", spaces)
print("frequencies:")
for ch, count in char_counts.items():
    print(repr(ch), count)

sum(条件 for ch in text) 用生成器表达式逐字判断,True 会按 1 计数;dict.fromkeys(text) 取得不重复字符,字典解析式一次构造“字符:频次”;count() 对每个字符重新扫描文本,因此代码短但长文本效率较低。

运行结果

示例输入:

Hi 22!

程序输出:

letters: 2
digits: 2
spaces: 1
frequencies:
'H' 1
'i' 1
' ' 1
'2' 2
'!' 1

逐个认识函数

下面只列出本程序实际用到的写法;先看参数如何传入,再看返回值怎样保存或输出。

函数/写法功能与返回值注意事项
input()读取一整行并返回字符串。输入中的空格会保留。
str.isascii()判断字符是否属于 ASCII 范围,返回 True 或 False。程序先判断 ASCII,再判断字母或数字。
str.isalpha()判断字符是否为字母,返回 True 或 False。配合 isascii() 后只统计 ASCII 英文字母。
str.isdigit()判断字符是否为数字字符,返回 True 或 False。配合 isascii() 后统计 0 到 9。
dict[key]读取或设置字典中 key 对应的值。先用 if 检查键是否存在,再决定是加一还是设为 1。
repr(ch)返回字符便于辨认的文本表示。空格会显示为带引号的形式。
print(...)输出一个或多个对象;返回 None。程序逐项输出统计结果。

一次循环完成统计

每读到一个字符,就检查它的类别并更新对应计数。随后用字典保存该字符的出现次数。

程序把首次出现和再次出现分开处理:第一次把次数设为 1,以后每出现一次就加 1。这样不用反复扫描文本,也不用把多个步骤压在一行里。

逐字符统计的过程

  1. for 循环每次从输入文本中取出一个字符 ch。
  2. 用 if 判断它是不是 ASCII 字母、数字或普通空格,对应计数变量加一。
  3. 检查 ch 是否已经是字典的键:是就把次数加一;不是就新增键并将次数设为 1。
  4. 最后遍历字典,repr(ch) 让空格也能看清。

字典计数小例子

第一次读到 "a":字典中还没有 "a",所以保存 1
再次读到 "a":字典中已有 "a",将次数从 1 改成 2

先判断键是否存在,再分别处理首次出现和重复出现,初学时比压缩成一行更容易跟踪。

代码如何运行

  1. 先按左侧题目给出的格式输入数据;程序通过 input() 读取,并在需要时转换数据类型。
  2. 程序自上而下执行语句;遇到条件、循环或函数调用时,按照右侧算法说明更新变量和处理数据。
  3. 最后由 print() 输出计算结果。可将左侧示例输入与输出逐项对照。

先自己跟踪一组小数据,记录循环前后变量的值;这比只看最终答案更容易理解程序。

自己动手试一试

试试空行、重复字符、中文和标点;分别确认哪些字符被计入英文字母、数字和空格。

先在 lx02.py 中独立完成,再运行参考程序比较结果。修改程序时一次只改一个条件或步骤。