在文本文件中计算字母数量。

6

我是一个初学者的Python程序员,正在尝试制作一个可以计算文本文件中字母数量的程序。以下是我的代码:

import string 
text = open('text.txt')
letters = string.ascii_lowercase
for i in text:
  text_lower = i.lower()
  text_nospace = text_lower.replace(" ", "")
  text_nopunctuation = text_nospace.strip(string.punctuation)
  for a in letters:
    if a in text_nopunctuation:
      num = text_nopunctuation.count(a)
      print(a, num)

如果文本文件包含hello bob,我希望输出为:
b 2
e 1
h 1
l 2
o 2

我的问题是,当文本文件包含多行文本或包含标点符号时,它不能正常工作。

8个回答

12
这是一种非常易于实现你想要的方法,使用Counter即可:
from string import ascii_lowercase
from collections import Counter

with open('text.txt') as f:
    print Counter(letter for line in f 
                  for letter in line.lower() 
                  if letter in ascii_lowercase)

您可以迭代生成的字典,以您想要的格式进行打印。

2
import string
fp=open('text.txt','r')
file_list=fp.readlines()
print file_list
freqs = {}
for line in file_list:
    line = filter(lambda x: x in string.letters, line.lower())
    for char in line:
        if char in freqs:
            freqs[char] += 1
        else:
            freqs[char] = 1

print freqs

1
你需要使用 collections.Counter
from collections import Counter
text = 'aaaaabbbbbccccc'
c = Counter(text)
print c

它打印出:
Counter({'a': 5, 'c': 5, 'b': 5})

你的text变量应该是:

import string
text = open('text.txt').read()
# Filter all characters that are not letters.
text = filter(lambda x: x in string.letters, text.lower())

要获取输出,您需要:
for letter, repetitions in c.iteritems():
    print letter, repetitions

在我的示例中,它打印出:

a 5
c 5
b 5

更多信息请参阅计数器文档

1
使用re:
import re

context, m = 'some file to search or text', {}
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
for i in range(len(letters)):
  m[letters[i]] = len(re.findall('{0}'.format(letters[i]), context))
  print '{0} -> {1}'.format(letters[i], m[letters[i]])

然而,使用Counter会使代码更加优雅简洁。


这对我来说运行得很好,除了无法正确打开我的文本文件。我尝试用open('text.txt')替换'some file to search or text'部分,但它没有起作用。我一直收到需要多个解包错误的提示。此外,我真的不理解您正在创建的变量上下文和m。您能帮助我吗? - user2752551
1
当然可以。只需使用以下代码: with open('file.txt', 'r') as file: context = file.read() 你可能已经遇到了 Python 著名的 yield 迭代器。 - user2567070

1

为了完整起见,如果你想不使用 Counter 来做到这一点,这里有另一种非常简短的方法,使用列表推导和内置的 dict

from string import ascii_lowercase as letters
with open("text.txt") as f:
    text = f.read().lower()
    print dict((l, text.count(l)) for l in letters)

f.read() 会将整个文件的内容读入 text 变量中(如果文件非常大可能不是一个好主意);然后我们使用列表推导式创建一个元组列表 (letter, count in text) 并将此元组列表转换为字典。在 Python 2.7+ 中,您也可以使用 {l: text.count(l) for l in letters},这甚至更短且更易读。

然而请注意,这将多次搜索文本,每个字母都要搜索一次,而Counter只扫描一次并一次性更新所有字母的计数。


0

另一种方式:

import sys
from collections import defaultdict

read_chunk_size = 65536

freq = defaultdict(int)
for c in sys.stdin.read(read_chunk_size):
    freq[ord(c.lower())] += 1

for symbol, count in sorted(freq.items(), key=lambda kv: kv[1], reverse=True):
    print(chr(symbol), count)

它输出最常见到最不常见的符号。

字符计数循环具有O(1)复杂度,并且可以处理任意大的文件,因为它按read_chunk_size块读取文件。


0

您可以将问题分成两个更简单的任务:

#!/usr/bin/env python
import fileinput # accept input from stdin and/or files specified at command-line
from collections import Counter
from itertools import chain
from string import ascii_lowercase

# 1. count frequencies of all characters (bytes on Python 2)
freq = Counter(chain.from_iterable(fileinput.input())) # read one line at a time

# 2. print frequencies of ascii letters
for c in ascii_lowercase:
     n = freq[c] + freq[c.upper()] # merge lower- and upper-case occurrences
     if n != 0:
        print(c, n)

-1
import sys

def main():
    try:
         fileCountAllLetters = file(sys.argv[1], 'r')
         print "Count all your letters: ", len(fileCountAllLetters.read())
    except IndexError:
         print "You forget add file in argument!"
    except IOError:
         print "File like this not your folder!"

main()
python file.py countlettersfile.txt Python 文件.py 计数字母文件.txt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接