2015-06-14 49 views
0

我需要创建一个函数,该函数将文本文件作为输入并返回大小为26的矢量,频率以每个字符(a到z)的百分比表示。这必须对大小写不敏感。所有其他字母(例如å)和符号应该被忽略。确定相对字母频率

我试过使用这里的一些答案,特别是'雅各'的答案。 Determining Letter Frequency Of Cipher Text

这是我到目前为止的代码:

def letterFrequency(filename): 
    #f: the text file is converted to lowercase 
    f=filename.lower() 
    #n: the sum of the letters in the text file 
    n=float(len(f)) 
    import collections 
    dic=collections.defaultdict(int) 
    #the absolute frequencies 
    for x in f: 
     dic[x]+=1 
    #the relative frequencies 
    from string import ascii_lowercase 
    for x in ascii_lowercase: 
     return x,(dic[x]/n)*100 

例如,如果我试试这个:

print(letterFrequency('I have no idea')) 
>>> ('a',14.285714) 

为什么它不能打印的字母都相对值?还有不在字符串中的字母,比如我的例子中的z?

以及如何让我的代码打印大小为26的矢量?

编辑:我试过使用计数器,但它打印('a':14.2857)和字母混合顺序。我只需要按顺序排列字母的相对频率!

回答

0
for x in ascii_lowercase: 
    return x,(dic[x]/n)*100 

该函数在循环的第一次迭代中返回。

取而代之的是,将其更改为返回元组的列表:

letters = [] 
for x in ascii_lowercase: 
    letters.append((x,(dic[x]/n)*100)) 
return letters 
+0

谢谢你,这个工作..但我如何删除在打印结果中的逗号?它打印[数字,数字,数字],但我真的想得到[数字号码]像数组 – Gliz

+0

@Gliz使用'letters.append((dic [x]/n)* 100)'并打印它使用'for e in letterFrequency('我不知道'):print(e,end ='')'。那是你要的吗? –

0

的问题是,在你的for循环:

for x in ascii_lowercase: 
    return x,(dic[x]/n)*100 

返回一个元组,所以它会在第一站迭代。

使用yield而不是return,这将变成一个按预期工作的发电机。

也是另一种方法,使其工作是返回一个列表理解:

return [x,(dic[x]/n)*100 for x in ascii_lowercase] 

但是,如果你的目的是计算项目,我电子书籍使用Counter类:

def letterFrequency(txt): 
    from collections import Counter 
    from string import ascii_lowercase 
    c=Counter(txt.lower()) 
    n=len(txt)/100. 
    return [(x, c[x]/n) for x in ascii_lowercase] 

正如你所看到的,c=Counter(txt.lower())使得迭代字符和保持计数的所有工作。该计数器的行为就像一个defaultdict

注意Counter也已经不错usefult方法,如c.most_common() ...