尽管按照@Michael 的建议Counter
从collections
库中使用是一种更好的方法,但我添加此答案只是为了改进您的代码。(我相信这对于新的 Python 学习者来说是一个很好的答案。)
从代码中的注释看来,您似乎想改进代码。而且我认为您可以用文字阅读文件内容(虽然通常我避免使用read()
函数并使用for line in file_descriptor:
某种代码)。
与words
字符串一样,在 for 循环中, for i in words:
循环变量i
不是单词而是 char。您正在迭代字符串中的字符,而不是迭代字符串中的单词words
。要理解这一点,请注意以下代码片段:
>>> for i in "Hi, h r u?":
... print i
...
H
i
,
h
r
u
?
>>>
因为逐个字符而不是逐个单词迭代给定的字符串不是您想要实现的,所以要逐个单词迭代,您应该使用split
Python 中字符串类的方法/函数。方法返回字符串中所有单词的列表,使用 str 作为分隔符(如果未指定,则在所有空格上拆分),可选择将拆分数限制为 num。
str.split(str="", num=string.count(str))
注意下面的代码示例:
分裂:
>>> "Hi, how are you?".split()
['Hi,', 'how', 'are', 'you?']
带拆分的循环:
>>> for i in "Hi, how are you?".split():
... print i
...
Hi,
how
are
you?
它看起来像你需要的东西。除了 word Hi,
because split()
,默认情况下,由空格分割,所以Hi,
被保存为单个字符串(显然)你不想要那个。
要计算文件中单词的频率,一个好的解决方案是使用正则表达式。但首先,为了简单起见,我将使用replace()
方法。该方法str.replace(old, new[, max])
返回字符串的副本,其中旧的出现已被替换为新的,可选地将替换次数限制为最大值。
现在检查下面的代码示例以查看我的建议:
>>> "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?
现在,如何计算频率:
一种方法是Counter
按照@Michael 的建议使用,但要使用您想要从空字典开始的方法。执行以下代码示例:
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()
,但dict[key]=default
如果 key 不在 dict 中,则会设置。因此,当一个新词第一次出现时,我0
在 dict 中使用setdefault
然后添加1
并分配给同一个 dict 来设置它。
我使用with open而不是 single编写了等效代码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}