Python 统计字符串中每个单词的长度(手把手讲解)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观
在文本处理和自然语言分析中,统计字符串中每个单词的长度是一项基础但重要的技能。无论是优化网页内容的可读性、分析用户评论的情感倾向,还是构建基础的文本摘要工具,这一技能都能帮助开发者快速提取关键信息。本文将从零开始讲解如何使用 Python 实现这一功能,并通过实际案例和代码示例,逐步引导读者掌握核心逻辑。
在 Python 中,字符串(String)是由字符组成的序列,而单词(Word)通常被定义为由字母、数字或下划线组成的连续字符片段。例如,在句子 "Hello world!" 中,"Hello" 和 "world" 是两个单词,而感叹号不属于单词的一部分。
字符串分割:将句子拆分为单词列表
统计单词长度的第一步是将字符串拆分为单词列表。Python 提供了 split()
方法,可以按照空格符分割字符串。
基础用法示例
sentence = "Python is a powerful language"
words = sentence.split()
print(words) # 输出:['Python', 'is', 'a', 'powerful', 'language']
这里,split()
方法默认以任意数量的空格作为分隔符,将句子拆分成单词列表。
处理标点符号
然而,实际场景中的字符串可能包含标点符号,例如:"Hello, world!"。此时,直接使用 split()
会保留标点符号,导致统计结果不准确。例如:
sentence_with_punctuation = "Hello, world!"
words = sentence_with_punctuation.split()
print(words) # 输出:['Hello,', 'world!']
此时,"Hello," 的长度为 7,但实际单词 "Hello" 的长度应为 5。因此,我们需要在分割前清理标点符号。
清理标点符号的两种方法
方法一:使用 strip()
去除两端标点
对于单词两端的标点,可以使用 strip()
方法去除:
def clean_word(word):
return word.strip(".,!?\"'") # 移除常见标点
sentence = "Hello, world! How's Python?"
cleaned_words = [clean_word(word) for word in sentence.split()]
print(cleaned_words) # 输出:['Hello', 'world', "How's", 'Python']
但这种方法无法处理单词中间的标点,例如 "don't" 或 "mother-in-law"。
方法二:使用正则表达式
正则表达式(Regex)可以更灵活地提取单词。Python 的 re
模块提供了 findall()
方法,可以匹配所有字母数字字符组成的单词:
import re
sentence = "Hello, world! How's Python? mother-in-law"
words = re.findall(r"\b[\w']+\b", sentence)
print(words) # 输出:['Hello', 'world', "How's", 'Python', 'mother-in-law']
这里,正则表达式 \b[\w']+\b
的含义是:
\b
:单词边界,确保匹配完整单词。[\w']
:匹配字母、数字、下划线或单引号(如 "don't")。+
:匹配一个或多个上述字符。
单词长度的统计方法
分割出单词列表后,统计每个单词的长度可以通过循环或列表推导式实现。
循环遍历法
sentence = "Python is fun"
words = sentence.split()
lengths = []
for word in words:
lengths.append(len(word))
print(lengths) # 输出:[6, 2, 3]
列表推导式法
列表推导式可以简化代码:
lengths = [len(word) for word in words]
处理大小写与特殊字符
在统计单词长度时,是否区分大小写?例如,"Python" 和 "PYTHON" 的长度均为 6,因此无需额外处理。但若需要统一大小写,可以用 lower()
或 upper()
方法:
cleaned_words = [word.lower() for word in words]
结合上述步骤,我们可以编写一个函数 count_word_lengths
,实现从输入字符串到输出单词长度的完整流程:
import re
def count_word_lengths(sentence):
# 使用正则表达式提取单词
words = re.findall(r"\b[\w']+\b", sentence)
# 统计每个单词的长度
lengths = [len(word) for word in words]
return lengths
example_sentence = "Hello! Let's code in Python. It's fun!"
print(count_word_lengths(example_sentence))
输出结果分析
对于输入句子 "Hello! Let's code in Python. It's fun!",输出结果的每个元素对应单词的长度:
- "Hello" → 5
- "Let's" → 5(注意单引号被保留,但长度统计时符号不算入)?
- 这里可能存在一个疑问:为什么 "Let's" 的长度是 5?实际上,"Let's" 包含 5 个字符(L-e-t-'-s),因此结果正确。
1. 排除停用词(Stop Words)
在自然语言处理中,常见停用词(如 "the", "a", "is")可能需要被排除。可以创建停用词列表并过滤:
STOP_WORDS = {"the", "a", "is", "in"}
def count_word_lengths(sentence):
words = re.findall(r"\b[\w']+\b", sentence)
filtered_words = [word for word in words if word.lower() not in STOP_WORDS]
lengths = [len(word) for word in filtered_words]
return lengths
test_sentence = "The quick brown fox jumps over the lazy dog"
print(count_word_lengths(test_sentence)) # 输出:[5, 6, 5, 5, 5, 4, 3]
2. 统计单词长度的频率分布
除了单独统计每个单词的长度,还可以统计不同长度的单词出现次数:
from collections import defaultdict
def word_length_distribution(sentence):
words = re.findall(r"\b[\w']+\b", sentence)
distribution = defaultdict(int)
for word in words:
length = len(word)
distribution[length] += 1
return distribution
distribution = word_length_distribution("Hello world Python")
print(distribution) # 输出:defaultdict(<class 'int'>, {5: 1, 6: 1, 5: 1}) → 需要修正?
注:此代码需要将 "Hello"(5)、"world"(5)、"Python"(6)的统计结果修正为 {5: 2, 6: 1}
。
对于长文本(如百万级字符),需要考虑代码的执行效率。以下是两种方法的对比:
方法 | 时间复杂度 | 适用场景 |
---|---|---|
split() + 循环清理 | O(n) | 简单场景,无需复杂符号处理 |
正则表达式 findall() | O(n) | 复杂符号处理,如保留连字符 |
示例性能测试
import timeit
def method1(sentence):
words = [word.strip(".,!?\"'") for word in sentence.split()]
return [len(word) for word in words]
def method2(sentence):
words = re.findall(r"\b[\w']+\b", sentence)
return [len(word) for word in words]
test_sentence = "a" * 100000 # 生成长字符串
print("Method1 Time:", timeit.timeit(lambda: method1(test_sentence), number=10))
print("Method2 Time:", timeit.timeit(lambda: method2(test_sentence), number=10))
实际测试中,split()
方法通常更快,但正则表达式在复杂场景下更灵活。
案例 1:分析用户评论的可读性
假设需要分析用户评论的平均单词长度,以评估文本的易读性:
reviews = [
"This app is great!",
"Terrible experience. Not user-friendly.",
"Average performance but good features"
]
def calculate_average_length(text):
lengths = count_word_lengths(text)
return sum(lengths)/len(lengths) if lengths else 0
for review in reviews:
print(f"Review: {review}\nAverage Length: {calculate_average_length(review):.1f}")
输出可能显示,平均长度越短的评论可能更易读。
案例 2:统计代码注释中的术语长度
在代码维护中,统计注释中术语的长度可以帮助优化文档:
comment = "The @classmethod decorator is useful for factory methods"
lengths = count_word_lengths(comment)
print(f"Longest word has {max(lengths)} characters") # 输出:10(decorator)
通过本文的讲解,读者可以掌握从基础字符串分割到复杂场景处理的完整流程。Python 提供了灵活的工具(如 split()
、正则表达式)和简洁的语法(如列表推导式),使得统计单词长度的任务变得高效且直观。无论是处理简单的英文句子,还是复杂的中文分词(需要额外库支持),这些方法都可作为基础框架。
在实际开发中,建议根据具体需求选择实现方式:
- 基础场景:使用
split()
+ 清理标点。 - 复杂场景:采用正则表达式处理特殊符号或保留连字符。
- 性能优化:通过
timeit
模块测试不同方法的效率。
掌握这一技能后,读者可以将其扩展到更多领域,例如构建文本摘要工具、分析社交媒体内容,或开发基础的自然语言处理应用。希望本文能为你的 Python 学习之路提供扎实的起点!