python单词中字母的位置频率词典

python单词中字母的位置频率词典,python,dictionary,list-comprehension,frequency,letter,Python,Dictionary,List Comprehension,Frequency,Letter,为了有效地获取字典中字符串code中字母的频率(给定字母ABC),我可以创建一个函数a-la(Python 3): 然后 给我 {'A': 0.2, 'C': 0.2, 'B': 0.6} 但是,我怎样才能沿着长度不等的字符串列表获得每个位置的频率呢?例如,mcode=['AAB','AA','ABC',''']应该给我一个嵌套结构,比如dict列表(其中每个dict是每个位置的频率): 我不知道如何在所有字符串中计算每个位置的频率,并将其包装在一个列表理解中。受其他SO的启发,用于字数计算,

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

然后

给我

{'A': 0.2, 'C': 0.2, 'B': 0.6}
但是,我怎样才能沿着长度不等的字符串列表获得每个位置的频率呢?例如,
mcode=['AAB','AA','ABC',''']
应该给我一个嵌套结构,比如dict列表(其中每个dict是每个位置的频率):

我不知道如何在所有字符串中计算每个位置的频率,并将其包装在一个列表理解中。受其他SO的启发,用于字数计算,例如,经过充分讨论的帖子,我认为来自
集合的计数器模块可能会有所帮助

这样理解-在单独的行中编写mcode字符串:

AAB
AA
ABC

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

例如,注释中简要说明了这些步骤。
不使用模块
集合的
计数器,因为一个位置的映射也包含在此位置不存在的字符以及fr的顺序顺序似乎并不重要

def freq(*字):
#所有字典都包含所有字符作为键,甚至
#如果某个位置不存在字符。
#创建按字符排序的字符列表。
chars=set()
用文字表示:
字符|=集合(字)
字符=已排序(字符)
#获取位置的数量。
max_position=max(单词中的单词的len(word))
#初始化字典的结果列表。
结果=[
dict((字符,0)表示字符中的字符)
用于范围内的位置(最大位置)
]
#计算字符数。
用文字表示:
对于范围内的位置(len(word)):
结果[位置][单词[位置]]+=1
#改变频率
对于范围内的位置(最大位置):
count=sum(结果[position].values())
对于char中的char:
Python 2的结果[position][char]/=count#float(count)
返回结果
#测试
从pprint导入pprint
mcode=['AAB','AA','ABC','']
pprint(频率(*mcode))
结果(Python 3):

[{'A':1.0,'B':0.0,'C':0.0},
{'A':0.66666666,'B':0.3333333,'C':0.0},
{'A':0.0,'B':0.5,'C':0.5}]

在Python 3.6中,字典甚至可以进行排序;早期版本可以使用
collections
中的
orderedict
,而不是
dict

您的代码根本没有效率:

  • 您首先需要定义要计数的字母
  • 您需要为每个不同的字母解析字符串
您可以使用
计数器

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}]

对于Python2,您可以使用
itertools.izip\u longest

一个更短的解决方案:

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)

我不太明白你的例子。第一个字符串'AAB'的输出应该是{'A':0.66,'C':0.0,'B':0.33}吗?另外,字符串中是否总是最多有3个不同的字母(ABC)?频率中的第一个位置是在AAA上计算的,在位置2它的AAB在位置3它的BC上。这有意义吗?在单独的行上对齐单词,然后沿着列找到频率。你可以做
itertools.zip_longest(*mcode)
并在这上面用你的
频率循环。你必须改变
len(code)
以反映正确的长度。顺便说一句:在Python 3中,您不需要
float()
@Allen,您现在更了解它了吗?-请参阅我的更新(我写的是每个位置的频率),这非常好-我总是忘记itertools
AAB
AA
ABC
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}]
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)