【问题标题】:Determing relative letter frequency确定相对字母频率
【发布时间】:2015-06-14 12:51:37
【问题描述】:

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

我尝试使用这里的一些答案,尤其是来自“Jacob”的答案。 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 的向量?

编辑:我尝试过使用 Counter,但它以混合顺序打印 ('a':14.2857) 和字母。我只需要有序序列中字母的相对频率!

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:
    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
    

    【讨论】:

    • 谢谢,这行得通.. 但是如何删除打印结果中的逗号?它打印 [number, number, number],但我真的很想像数组一样得到 [number number number]
    • @Gliz 使用letters.append((dic[x]/n)*100) 并使用for e in letterFrequency('I have no idea'): print(e, end = ' ') 打印它。这就是你想要的吗?
    【解决方案2】:

    问题是在您的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 也有很好用的方法,比如c.most_common()...

    【讨论】:

      【解决方案3】:

      嘿嘿!这是您的解决方案。我已经使用了脚本您提出的问题作为示例 :) (我所做的只是将它制作成一个字符串,称为字符串)

      string = ' your text '
          alpha_count = {}
          string = string.lower()
          for alpha in string:
              match = re.search("[a-z]", alpha)
              boolean = bool(match)
              if boolean:
                  if alpha in alpha_count:
                      alpha_count[alpha] += 1
                  else:
                      alpha_count[alpha] = 1
          print(alpha_count)
      

      输出:

      {'i': 18,
       'n': 18,
       'e': 47,
       'd': 7,
       't': 32,
       'o': 18,
       'c': 13,
       'r': 21,
       'a': 19,
       'f': 10,
       'u': 8,
       'h': 12,
       'k': 1,
       's': 19,
       'x': 3,
       'l': 9,
       'p': 4,
       'v': 3,
       'z': 2,
       'w': 3,
       'q': 2,
       'y': 4,
       'm': 6,
       'b': 4,
       'g': 2,
       'j': 1}
      

      如果您想要排序视图,请在执行上述代码后使用此代码。

      alpha_items = alpha_count.items()
      sorted_items = sorted(alpha_items)
      print(sorted_items)
      

      结果:

      [('a', 19), ('b', 4), ('c', 13), ('d', 7), ('e', 47), ('f', 10), ('g', 2), ('h', 12), ('i', 18), ('j', 1), ('k', 1), ('l', 9), ('m', 6), ('n', 18), ('o', 18), ('p', 4), ('q', 2), ('r', 21), ('s', 19), ('t', 32), ('u', 8), ('v', 3), ('w', 3), ('x', 3), ('y', 4), ('z', 2)]
      

      谢谢!!!

      【讨论】:

      • 警告!不要忘记在文本中使用反斜杠作为撇号和引号。例如,如果你有一个像 Jacob's 这样的词,应该写 Jacob\'s "Jacob" 应该写成 \"Jacob\" 在使用每个这样的字符之前使用反斜杠
      猜你喜欢
      • 2010-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-20
      • 2012-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多