2016-07-21 72 views
0

我想要此代码执行的操作是读取文本文件,并打印出每个单词在百分比中的含义。它几乎作品..计算每个单词在文本中发生的次数

我无法弄清楚如何打印出从最高排序产生到最低(我有它在一个点时,我是复制/粘贴其他民族的代码,我想我进口藏品和计数器,我不知道)

但另一个问题是它读通过我的整个列表,这对较小的文本文件很好,但较大的只是吃了我的终端,我希望它只打印一次字,而不是每个实例一次

name = raw_input('Enter file:') 
handle = open(name, 'r') 
text = handle.read() 
words = text.split() 

def percent(part, whole): 
    return 100 * float(part)/float(whole) 

total = len(words) 

counts = dict() 
for word in words: 
    counts[word] = counts.get(word,0) + 1 

print "\n" 
print"Total Words\n", total 
print"\n" 

for word in words: 
    print word, percent(counts[word],total),"%" 
+1

更好地使用'collections.Counter'而不是'dict'。像这样'计数=计数器(单词)'。与'dict'的'for'循环相比,这将更快,更具可读性。 – Arnial

+0

欢迎来到Stack Overflow。在未来提出更好的问题时,一个小小的提示就是试图在标题中简要描述你的问题。例如,对于这篇文章,更好的标题是“按频率打印文字”。这将使人们在将来更容易搜索他们自己问题的答案,并且还可以帮助那些试图回答您的问题一目了然的人。除此之外,这是一个非常好的问题。你是我见过的第一批正确使用减价的人之​​一。 –

回答

1

您可以像这样遍历字典:

for word in counts: 
    print word, counts[word] 

这将在字典中打印每个键一次。 对于排序,你应该看看内置sorted()功能:https://docs.python.org/3.4/library/functions.html#sorted

+0

不应该是'换个字,算在counts.itertools()'中?因为,“换句话说,计数”对我来说是一个错误。 – xgord

+0

你是对的'换句话说,计数'不起作用。我的错。它应该是'计数字'(迭代键)或'换字,count.iteritems()'(遍历键和值) – akn320

0

关于第一个问题,你可以收藏的OrderedDict这样:

sortedCounts = collections.OrderedDict(sorted(counts.items(),key=lambda t: t[1])) 

如要只打印一次每个字:

for key, value in sortedCounts.iteritems(): 
    print key, percent(value,total),"%" 

希望有帮助

+0

这应该按字母顺序排序吗?导致这发生在我身上,我试图按高到低排序,但它确实只输出了一次 –

+0

对不起,我将编辑它。 –

0

您的代码非常接近可行;我只看到几个问题导致您的问题:

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'] 
+0

检查“1print”和“totalprint”等单词。他们似乎是因为你用''''而不是'''替换''n''。 – chapelo

+0

@chapelo感谢您的注意。我的意思是去除多余的'replace()'调用,因为正则表达式摆脱了换行符,但忘了。答案现在已经更新。 – xgord

+0

'formatted.extend(re.findall('\ w +',w))'有没有关于这个的教程?我看到它的工作原理,但不知道如何/为什么 –

相关问题