虽然使用@Michael 建议的collections 库中的Counter 是一种更好的方法,但我添加此答案只是为了改进您的代码。 (我相信这对于新的 Python 学习者来说是一个很好的答案。)
从您的代码中的评论看来,您似乎想要改进您的代码。而且我认为您可以用文字阅读文件内容(虽然我通常避免使用read() 函数并使用for line in file_descriptor: 类型的代码)。
由于words 是一个字符串,在for 循环中,for i in words: 循环变量i 不是一个词,而是一个字符。您正在迭代字符串中的字符,而不是迭代字符串words 中的单词。要理解这一点,请注意以下代码 sn-p:
>>> for i in "Hi, h r u?":
... print i
...
H
i
,
h
r
u
?
>>>
因为逐字符而不是逐单词迭代给定字符串不是您想要实现的,所以要逐单词迭代您应该使用 Python 中字符串类中的 split 方法/函数。
@ 987654321@ 方法 返回字符串中所有单词的列表, 使用 str 作为分隔符(如果未指定,则在所有空格上拆分),可选择将拆分次数限制为编号。
注意下面的代码示例:
拆分:
>>> "Hi, how are you?".split()
['Hi,', 'how', 'are', 'you?']
带分割的循环:
>>> for i in "Hi, how are you?".split():
... print i
...
Hi,
how
are
you?
它看起来像你需要的东西。除了单词Hi,,因为split() 默认情况下会被空格分割,所以Hi, 被保存为单个字符串(显然)你不希望这样。
要计算文件中单词的频率,一个好的解决方案是使用正则表达式。但首先,为了简单起见,我将使用replace() 方法。 str.replace(old, new[, max]) 方法返回字符串的副本,其中出现的 old 已替换为 new,可选地将替换次数限制为最大。
现在检查下面的代码示例,看看我的建议:
>>> "Hi, how are you?".split()
['Hi,', 'how', 'are', 'you?'] # it has , with Hi
>>> "Hi, how are you?".replace(',', ' ').split()
['Hi', 'how', 'are', 'you?'] # , replaced by space then split
循环:
>>> for word in "Hi, how are you?".replace(',', ' ').split():
... print word
...
Hi
how
are
you?
现在,如何计算频率:
一种方法是按照@Michael 的建议使用Counter,但要使用您希望从空字典开始的方法。执行以下代码示例:
words = f.read()
wordfreq = {}
for word in .replace(', ',' ').split():
wordfreq[word] = wordfreq.setdefault(word, 0) + 1
# ^^ add 1 to 0 or old value from dict
我在做什么?因为最初wordfreq 是空的,所以你不能第一次将它分配给wordfreq[word](它会引发关键异常错误)。所以我使用了setdefault dict 方法。
dict.setdefault(key, default=None) 类似于 get(),但如果 key 不在 dict 中,则会设置 dict[key]=default。所以第一次当一个新词出现时,我使用setdefault在dict中设置0,然后添加1并分配给同一个dict。
我已经使用with open 而不是单个open 编写了等效代码。
with open('~/Desktop/file') as f:
words = f.read()
wordfreq = {}
for word in words.replace(',', ' ').split():
wordfreq[word] = wordfreq.setdefault(word, 0) + 1
print wordfreq
运行如下:
$ cat file # file is
this is the textfile, and it is used to take words and count
$ python work.py # indented manually
{'and': 2, 'count': 1, 'used': 1, 'this': 1, 'is': 2,
'it': 1, 'to': 1, 'take': 1, 'words': 1,
'the': 1, 'textfile': 1}
使用re.split(pattern, string, maxsplit=0, flags=0)
只需更改 for 循环:for i in re.split(r"[,\s]+", words):,它应该会产生正确的输出。
编辑:最好找到所有字母数字字符,因为您可能有多个标点符号。
>>> re.findall(r'[\w]+', words) # manually indent output
['this', 'is', 'the', 'textfile', 'and',
'it', 'is', 'used', 'to', 'take', 'words', 'and', 'count']
使用 for 循环:for word in re.findall(r'[\w]+', words):
如果不使用read(),我将如何编写代码:
文件是:
$ cat file
This is the text file, and it is used to take words and count. And multiple
Lines can be present in this file.
It is also possible that Same words repeated in with capital letters.
代码是:
$ cat work.py
import re
wordfreq = {}
with open('file') as f:
for line in f:
for word in re.findall(r'[\w]+', line.lower()):
wordfreq[word] = wordfreq.setdefault(word, 0) + 1
print wordfreq
使用lower()将大写字母转换为小写字母。
输出:
$python work.py # manually strip output
{'and': 3, 'letters': 1, 'text': 1, 'is': 3,
'it': 2, 'file': 2, 'in': 2, 'also': 1, 'same': 1,
'to': 1, 'take': 1, 'capital': 1, 'be': 1, 'used': 1,
'multiple': 1, 'that': 1, 'possible': 1, 'repeated': 1,
'words': 2, 'with': 1, 'present': 1, 'count': 1, 'this': 2,
'lines': 1, 'can': 1, 'the': 1}