您的代码非常接近可行;我只看到几个问题导致您的问题:
P1:您的代码不考虑非单词字符。例如,word;
,word.
和word
都将被视为唯一的单词。
text = handle.read()
words = text.split()
P2:您遍历单词整个名单,其中包括,而不是你在counts
唯一列表重复。所以当然你会多次打印每个单词。
for word in words:
P3:您打开该文件,但永远不会关闭它。不完全是你的代码有问题,但有待改进。这就是为什么通常鼓励使用with open(...):
语法的原因,因为它会为您处理关闭文件。
handle = open(name, 'r')
这里是你的代码的一些修正:当该程序运行
#!/usr/bin/python
import re
name = raw_input('Enter file:')
def percent(part, whole):
return 100 * float(part)/float(whole)
# better way to open files, handles closing the file
with open(name, 'r') as handle:
text = handle.read()
words = text.split()
# get rid of non-word characters that are messing up count
formatted = []
for w in words:
formatted.extend(re.findall(r'\w+', w))
total = len(formatted)
counts = dict()
for word in formatted:
counts[word] = counts.get(word,0) + 1
print "\n"
print"Total Words\n", total
print"\n"
# iterate over the counts dict instead of the original word list
# this way each word is only printed once
for word,count in counts.iteritems():
print word, percent(counts[word],total),"%"
输出:
Total Words
79
text 2.53164556962 %
float 2.53164556962 %
as 1.26582278481 %
file 1.26582278481 %
in 3.79746835443 %
handle 2.53164556962 %
counts 6.32911392405 %
total 3.79746835443 %
open 1.26582278481 %
findall 1.26582278481 %
for 3.79746835443 %
0 1.26582278481 %
percent 2.53164556962 %
formatted 5.06329113924 %
1 1.26582278481 %
re 2.53164556962 %
dict 1.26582278481 %
usr 1.26582278481 %
Words 1.26582278481 %
print 5.06329113924 %
import 1.26582278481 %
split 1.26582278481 %
bin 1.26582278481 %
return 1.26582278481 %
extend 1.26582278481 %
get 1.26582278481 %
python 1.26582278481 %
len 1.26582278481 %
iteritems 1.26582278481 %
part 2.53164556962 %
words 2.53164556962 %
Enter 1.26582278481 %
100 1.26582278481 %
with 1.26582278481 %
count 1.26582278481 %
word 7.59493670886 %
name 2.53164556962 %
read 1.26582278481 %
raw_input 1.26582278481 %
n 3.79746835443 %
r 1.26582278481 %
w 3.79746835443 %
Total 1.26582278481 %
whole 2.53164556962 %
def 1.26582278481 %
编辑 - 这个词的添加解释格式
formatted.extend(re.findall(r'\w+', w))
的细分:
1:列表的extend
函数获取列表并将其附加到给定列表。例如:
listA = [1,2,3]
listB = [4,5,6]
listA.extend(listB)
print(listA)
# [1, 2, 3, 4, 5, 6]
2:re.findall(r'\w+', w))
该表达式使用regular expressions提取我们关心的字符串的仅一部分。 python的正则表达式是tutorial。
基本上,re.findall(x, y)
返回y
中与x
中列出的正则表达式模式匹配的所有子字符串的列表。在我们的例子中,\w
表示所有单词字符(即字母数字字符),而+
表示前面的一个或多个模式。所以放在一起,\w+
表示一个或多个单词字符。
我可能通过给字符串变量命名,我们在w
上进行搜索,但是请记住模式中的\w
与作为字符串的w
变量无关。
word = 'heres some1; called s0mething!'
re.findall(r'\w+', word)
# ['heres', 'some1', 'called', 's0mething']
更好地使用'collections.Counter'而不是'dict'。像这样'计数=计数器(单词)'。与'dict'的'for'循环相比,这将更快,更具可读性。 – Arnial
欢迎来到Stack Overflow。在未来提出更好的问题时,一个小小的提示就是试图在标题中简要描述你的问题。例如,对于这篇文章,更好的标题是“按频率打印文字”。这将使人们在将来更容易搜索他们自己问题的答案,并且还可以帮助那些试图回答您的问题一目了然的人。除此之外,这是一个非常好的问题。你是我见过的第一批正确使用减价的人之一。 –