为了有效地获取字母的频率(在字典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的频率。
答案 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}]
。