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 学习之路提供扎实的起点!

最新发布