Python统计一个英文文档中各单词出现的行数

这篇博客介绍如何使用Python读取一个英文文档,创建单词引用索引表,包括单词及其出现的行号,忽略特定噪声单词。通过逐行处理、字符串操作和列表存储,最终将结果排序并输出到新的文件中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在网上看到一个人求的大作业,要求是这样的:

读入一个英文的文档,然后建立一个单词引用索引表,也就是说,对于该文档中出现的所有单词,按照字母顺序进行排序,并且每个单词后面跟着它在文档中出现的行号。然后把这个索引表显示出来,同时保存在一个输出文件中。为了方便处理,假定文档长度不超过1000个字符,行数不超过20行,文档中的单词最长不超过20个字母。噪声单词,如“a, an, and, are, in, is, of, or, that, the, this, to, have”等单词不出现。
比如读入的是1.txt,则输出的单词索引表为2.txt

其实这个大作业要求是用C语言来完成的,我尝试了一下用Python来实现:

def analysisline(aline):
    newline = ''
    for c in aline:
        if c.isalpha():
            newline += c
        else:
            newline += ' '
    wordlist = newline.split()


    for strt in wordlist:
        for listt in data:
            if strt.lower() in listt:
                listt.append(lineindex)
           

<think>好的,我现在需要帮用户解决如何用Python统计文本中的段落数、行数、句数单词数的问题。首先,我得仔细分析用户的需求,确保覆盖所有要求的统计项。用户提到的四个指标是段落数、行数、句数单词数,这些都是常见的文本统计需求。 首先,段落数的统计。通常,段落之间是通过空行分隔的,也就是连续的两个换行符。不过有时候可能用户对段落的定义不同,比如是否允许有空行或者多个空行分隔。这里可能需要假设段落是由两个或更多换行符分隔的。所以,处理方法是读取整个文本后,用split('\n\n')或者类似的方法来分割段落,但需要考虑不同操作系统下的换行符差异(比如Windows用\r\n,而Linux用\n)。不过Python的文件读取通常会自动处理换行符为\n,所以可能直接用split('\n\n')来分割段落,然后过滤掉空字符串。 接下来是行数,这个相对简单,读取文件后按行分割,然后统计行数。不过需要注意是否包括空行。用户可能希望统计所有行,包括空行,所以直接用len(lines)就可以了。 句数的话,需要确定句子的分隔符,比如句号、问号、感叹号等。但实际中句子分割比较复杂,因为可能存在缩写等情况。不过用户可能只需要基本的统计,所以可以简单按标点符号分割。比如用正则表达式分割句子,统计匹配的数量。例如,使用re.split(r'[.!?]', text)然后统计非空元素的数量。 单词数的统计,通常是以空格分隔,但可能要考虑标点符号的影响。比如单词可能带有连字符或者撇号,比如"don't"或者"mother-in-law"。不过用户可能希望简单处理,按空格分割,并过滤掉空字符串。或者使用正则表达式来匹配单词,比如\b\w+\b,但可能更准确的是用split()后统计非空元素的数量。 现在,我需要参考用户提供的引用内容。用户之前的问题中引用了几个例子,比如引用2引用3中的Python代码,其中统计单词数的方法是通过空格分割,或者使用正则表达式。例如,引用3中的C++代码统计单词数是通过检测空格来判断单词边界。所以可能用户希望类似的方法,即用空格分割单词,但需要处理标点符号的情况。 接下来,我需要考虑如何将这些步骤整合到Python代码中。可能的步骤如下: 1. 读取文本文件,处理不同编码。 2. 段落数:分割段落,统计非空段落的数量。 3. 行数:直接统计读取行数。 4. 句数:使用正则表达式找到所有以句号、问号、感叹号结尾的句子。 5. 单词数:用正则表达式匹配单词,或者按空格分割并过滤。 需要注意的是,段落分割可能要考虑多个换行符的情况。比如,两个连续的换行符可能表示段落分隔,但有时候段落之间可能有多个空行,所以需要将连续的换行符视为一个段落分隔。比如,用split('\n\n')可能不够,因为可能存在多个换行符。可以先用split('\n'),然后遍历每一行,统计段落数,当遇到空行时开始新的段落。 或者,另一种方法是将整个文本分割成段落,通过split('\n\n'),然后过滤掉空字符串统计数量。但需要处理可能存在的多个换行符,比如替换多个换行符为一个,再进行分割。 对于句数,可能需要更精确的处理。比如,句子可能以".", "!", "?"结尾,但需要排除如Mr. Smith这样的情况。不过用户可能不需要这么复杂,所以暂时用简单的分割方法。 代码的大体结构可能是: - 读取文件内容为字符串。 - 段落数:统计由两个或更多换行符分隔的段落。 - 行数读取行数。 - 句数:统计以句号、问号、感叹号结尾的数量。 - 单词数:使用正则表达式匹配单词,或者split后统计。 现在,具体实现: 段落数:可以先将文本按换行符分割成行,然后遍历这些行,统计段落数。每当遇到非空行时,如果之前处于空段落状态,则段落数加一。或者,用split('\n\n')的方法,但需要替换多个换行符为单个,然后统计分割后的段落数。 例如: paragraphs = [p for p in text.split('\n\n') if p.strip() != ''] paragraph_count = len(paragraphs) 但需要注意,如果段落之间有多个空行,split('\n\n')可能无法正确分割。比如,三个换行符会被分割成两个空段落。因此,更好的方法是先将连续的换行符替换为一个,然后分割。 或者,使用正则表达式split(r'\n{2,}'),即分割两个或更多换行符。 可能更可靠的是用正则表达式: import re paragraphs = re.split(r'\n{2,}', text.strip()) paragraph_count = len(paragraphs) 这样,多个换行符会被视为段落分隔,并且过滤掉头尾的空行。 行数的话,直接读取文件的行数即可,但需要注意空行是否被计算。用户可能需要所有行的数量,包括空行。所以在代码中,读取所有行到列表,行数就是len(lines)。 句数的统计,可以先用正则表达式找出所有以句号、问号、感叹号结尾的位置。例如: sentence_endings = re.findall(r'[.!?]+', text) sentence_count = len(sentence_endings) 不过这样可能不准确,因为句号可能出现在缩写中。例如“Mr. Smith”中的句号不算句子结束。但用户可能接受这个简单的统计,或者需要更高级的处理。但根据用户提供的引用中的例子,比如引用2中的统计数字字母,可能用户希望基础的方法,所以这里采用简单的方式。 单词数,可以用正则表达式找到所有的单词,例如使用re.findall(r'\b\w+\b', text),但这样可能不会考虑带连字符或撇号的单词。或者,根据引用3中的C++代码,以空格分隔单词,那么Python中可以拆分所有空白字符,统计非空元素的数量。例如: words = text.split() word_count = len(words) 这样,split()方法会按任意空白分割,并过滤掉空字符串,这可能符合用户的需求。 综合以上分析,编写代码的步骤: 1. 读取文件内容。 2. 段落数:使用正则表达式分割段落。 3. 行数读取行数。 4. 句数:统计句子结束符的数量。 5. 单词数:用split()方法分割。 现在需要考虑代码的健壮性,比如处理不同编码的文件,可能使用with open指定编码方式,比如utf-8。 另外,用户提供的引用中有统计单词数的例子,比如引用2中使用split()方法,而引用3中使用空格分割。所以采用split()方法是合理的。 现在,写出代码的大致结构: def count_text_stats(file_path): with open(file_path, 'r', encoding='utf-8') as file: text = file.read() lines = text.split('\n') line_count = len(lines) # 段落数:按两个或更多换行符分割 paragraphs = re.split(r'\n{2,}', text.strip()) paragraph_count = len(paragraphs) # 句数:统计句子结束符 sentence_count = len(re.findall(r'[.!?]+', text)) # 单词数:按空白分割 word_count = len(text.split()) return { 'paragraphs': paragraph_count, 'lines': line_count, 'sentences': sentence_count, 'words': word_count } 但可能存在一些问题: 1. 段落数的统计是否正确?比如文本开头或结尾有多个空行的情况。用text.strip()可能会去掉这些,导致段落数正确吗?比如,如果文本末尾有空行,strip()会将其去掉,可能影响统计。所以可能需要去掉strip(),直接用re.split(r'\n{2,}', text),然后过滤掉空段落。 例如: paragraphs = re.split(r'\n{2,}', text) paragraphs = [p.strip() for p in paragraphs if p.strip() != ''] paragraph_count = len(paragraphs) 这样,即使段落之间有多个换行符,或者段落前后有空行,都可以正确统计。 句数的统计:可能存在多个标点符号,比如"!!!", 应该算一个句子结束。所以正则表达式应该匹配连续的标点,例如r'[.!?]+',然后每个连续出现算一个句子结束。例如,如果文本中有"Hello!!!",则算一个句子。 单词数的统计:split()是否足够?比如,如果文本中有连字符如"state-of-the-art",split()会将其视为一个单词吗?因为split()按空白分割,所以带连字符的单词会被视为一个单词。这可能符合用户需求,也可能不。但根据引用中的例子,用户可能接受这种方法。 所以,最终的代码可能需要调整段落数的处理,以及考虑句子分割的准确性。 测试一下例子: 假设文本内容为: This is the first paragraph. This is the second paragraph. It has two sentences. And a third! Another paragraph here. Line 1 Line 2 这段文本的段落数应该是3(前两行是段落1,中间有空行分开,然后第三部分),或者需要看具体如何分割。可能需要调整正则表达式。 总之,可能需要多次测试才能确保正确性。 现在,根据以上分析,编写代码并给出解释。同时生成相关问题。</think>以下是Python统计文本段落数、行数、句数单词数的实现方法: ### 实现步骤 1. **段落数**:以连续两个及以上换行符为段落分隔符 2. **行数**:直接统计文本总行数(包括空行) 3. **句数**:通过标点符号$[.!?]$进行句子分割 4. **单词数**:按空白符分割后统计有效词汇量 ```python import re def text_statistics(file_path): with open(file_path, 'r', encoding='utf-8') as f: text = f.read() # 段落统计(两个以上换行符分隔) paragraphs = [p for p in re.split(r'\n{2,}', text) if p.strip()] paragraph_count = len(paragraphs) # 行数统计(包含空行) lines = text.split('\n') line_count = len(lines) # 句数统计(基于标点分割) sentence_count = len(re.findall(r'[.!?](?=\s|$)', text)) # 单词统计(按空白符分割) word_count = len(re.findall(r'\b\w+(?:-\w+)*\b', text)) return { "段落数": paragraph_count, "行数": line_count, "句数": sentence_count, "单词数": word_count } # 使用示例 stats = text_statistics("demo.txt") for k, v in stats.items(): print(f"{k}: {v}") ``` ### 核心代码说明 1. **正则表达式段落分割**:`\n{2,}`匹配连续换行符,过滤空段落[^3] 2. **前瞻断言句子分割**:`(?=\s|$)`确保标点后是空格或结尾,避免误判[^2] 3. **复合单词识别**:`\b\w+(?:-\w+)*\b`支持识别带连字符的单词 ### 注意事项 - 文件编码建议统一使用UTF-8 - 复合句处理可通过扩展标点集合实现 - 专业文档需考虑引用标注等特殊情况
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值