我是Python的新手,我确信有一种更简单的方法来完成我需要的东西但是这里有。
我正在尝试创建一个程序,该程序在名为inputList
的字母列表上执行频率分析,并检索2个字母对并将它们添加到另一个字典中。所以我需要它用所有2个字母对填充第二个dictonary。
我对如何做到这一点有一个粗略的想法,但是我对语法有点困惑使它工作。
for bigram in inputList:
bigramDict[str(bigram + bigram+1)] = 1
其中bigram + 1是下一次迭代中的字母
作为一个例子,如果我要在inputList
中使用“stackoverflow”文本,我需要首先将字母“st”作为键,将1作为值。在第二次迭代“ta”作为关键等等。我遇到的问题是在不转移到下一次迭代的情况下,在下一次迭代中重新获取变量的值。
我希望我能清楚地解释自己。谢谢你的帮助
答案 0 :(得分:5)
获得序列的n-gram的直接方法是切片:
def ngrams(seq, n=2):
return [seq[i:i+n] for i in range(len(seq) - n + 1)]
将此与collections.Counter
相结合,您就可以了:
from collections import Counter
print Counter(ngrams("abbabcbabbabr"))
如果你需要ngrams()
懒惰:
from collections import deque
def ngrams(it, n=2):
it = iter(it)
deq = deque(it, maxlen=n)
yield tuple(deq)
for p in it:
deq.append(p)
yield tuple(deq)
(有关后者的更优雅代码,请参阅below)。
答案 1 :(得分:3)
使用zip将zip字符串复制到自身的副本1
获取这样的bigraphs:
s = "stackoverflow"
zip(s,s[1:])
给出:
[('s', 't'), ('t', 'a'), ('a', 'c'), ('c', 'k'), ('k', 'o'), ('o', 'v'), ('v', 'e'), ('e', 'r'), ('r', 'f'), ('f', 'l'), ('l', 'o'), ('o', 'w')]
Trigraphs也很容易:
zip(s,s[1:],s[2:])
给出:
[('s', 't', 'a'), ('t', 'a', 'c'), ('a', 'c', 'k'), ('c', 'k', 'o'), ('k', 'o', 'v'), ('o', 'v', 'e'), ('v', 'e', 'r'), ('e', 'r', 'f'), ('r', 'f', 'l'), ('f', 'l', 'o'), ('l', 'o', 'w')]
您可以使用元组作为字典的键......或者更好地使用Counter或default_dict对象来执行计数。祝好运!
答案 2 :(得分:3)
from collections import Counter
from itertools import islice, izip, tee
def pairs(iterable):
a, b = tee(iterable)
for pair in izip(a, islice(b, 1, None)):
yield pair
print Counter(pairs("stackoverflow"))
或更简单的版本:
def pairs(iterable):
it = iter(iterable)
last = next(it)
for c in it:
yield last, c
last = c
任意n
的广义版本:
def ngrams(iterable, n=2):
return izip(*[islice(it, i, None) for i, it in enumerate(tee(iterable, n))])
答案 3 :(得分:1)
保留上一个字母的变量?第一次迭代,您只需获取第一个字母,不做任何其他操作。
ADDENDUM:这种方法至少不需要浪费任何更多的内存而不是简单的变量来存储一个字母,没有多余的元组或任何东西。