python位置频率字母词典

时间:2017-04-29 07:30:55

标签: python dictionary list-comprehension frequency letter

为了有效地获取字母的频率(在字典ABC中的字典中给出字母code,我可以创建一个函数a-la(Python 3):

def freq(code):
   return{n: code.count(n)/float(len(code)) for n in 'ABC'}

然后

code='ABBBC'   
freq(code)

给我

{'A': 0.2, 'C': 0.2, 'B': 0.6}

但是如何在不等长度的字符串列表中获取每个位置的频率?例如mcode=['AAB', 'AA', 'ABC', '']应该给我一个嵌套结构,比如dict列表(每个dict是每个位置的频率):

[{'A': 1.0, 'C': 0.0, 'B': 0.0}, 
 {'A': 0.66, 'C': 0.0, 'B': 0.33},
 {'A': 0.0, 'C': 0.5, 'B': 0.5}]

我无法弄清楚如何在所有字符串中执行每个位置的频率,并将其包含在列表理解中。灵感来自其他SO的字数,例如讨论得很好Python: count frequency of words in a list我认为collections中的Counter模块可能是一个帮助。

像这样理解它 - 在单独的行上写mcode字符串:

AAB
AA
ABC

然后我需要的是在dict列表中字母ABC的列式频率(AAA,AAB,BC),其中每个列表元素是每列ABC的频率。

3 个答案:

答案 0 :(得分:1)

示例,这些步骤很快在评论中解释。未使用模块Counter的{​​{1}},因为位置的映射还包含在此位置不存在的字符,并且频率顺序似乎并不重要。

collections

结果(Python 3):

def freq(*words):
    # All dictionaries contain all characters as keys, even
    # if a characters is not present at a position.
    # Create a sorted list of characters in chars.
    chars = set()
    for word in words:
        chars |= set(word)

    chars = sorted(chars)

    # Get the number of positions.
    max_position = max(len(word) for word in words)

    # Initialize the result list of dictionaries.
    result = [
        dict((char, 0) for char in chars)
        for position in range(max_position)
    ]

    # Count characters.
    for word in words:
        for position in range(len(word)):
            result[position][word[position]] += 1

    # Change to frequencies
    for position in range(max_position):
        count = sum(result[position].values())
        for char in chars:
            result[position][char] /= count  # float(count) for Python 2

    return result


# Testing
from pprint import pprint
mcode = ['AAB', 'AA', 'ABC', '']
pprint(freq(*mcode))

在Python 3.6中,字典甚至是排序的;早期版本可以使用[{'A': 1.0, 'B': 0.0, 'C': 0.0}, {'A': 0.6666666666666666, 'B': 0.3333333333333333, 'C': 0.0}, {'A': 0.0, 'B': 0.5, 'C': 0.5}] 中的OrderedDict代替collections

答案 1 :(得分:1)

更短的解决方案:

from itertools import zip_longest

def freq(code):
    l = len(code) - code.count(None)
    return {n: code.count(n)/l for n in 'ABC'}

mcode=['AAB', 'AA', 'ABC', '']
results = [ freq(code) for code in zip_longest(*mcode) ]
print(results)

答案 2 :(得分:0)

您的代码根本没有效率:

  • 您首先需要定义您想要计算的字母数
  • 您需要解析每个不同字母的字符串

您可以使用http://127.0.0.1:8000/charts/

Counter

对于Python2,您可以使用import itertools from collections import Counter mcode=['AAB', 'AA', 'ABC', ''] all_letters = set(''.join(mcode)) def freq(code): code = [letter for letter in code if letter is not None] n = len(code) counter = Counter(code) return {letter: counter[letter]/n for letter in all_letters} print([freq(x) for x in itertools.zip_longest(*mcode)]) # [{'A': 1.0, 'C': 0.0, 'B': 0.0}, {'A': 0.6666666666666666, 'C': 0.0, 'B': 0.3333333333333333}, {'A': 0.0, 'C': 0.5, 'B': 0.5}]