2012-06-21 31 views
4

我對Python很陌生,我相信有一種更簡單的方法來完成我所需要的,但是這裏有。在for循環中獲取下一個變量

我試圖創建一個程序,對名爲inputList的字母列表執行頻率分析,並檢索2個字母對,並將它們添加到另一個字典中。所以我需要它用所有2個字母對來填充第二個冠詞。

我有一個大概的想法,我可以做到這一點,但我有點卡住的語法,使其工作。

for bigram in inputList: 
    bigramDict[str(bigram + bigram+1)] = 1 

凡二元+ 1是下一個迭代

作爲一個例子,信,如果我是有文字「計算器」在inputList我需要首先把字母「ST」爲鍵和1作爲值。在第二次迭代「ta」爲關鍵等。我遇到的問題是重新獲取變量在下一次迭代時的值,而不移動到下一次迭代。

我希望我清楚地解釋自己。感謝您的幫助

回答

5

一個直接的方法來獲得正克的序列切片:

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後者更優雅的代碼)。

+0

是串在Python的O(1)操作或O(n)的操作下標?這要麼是令人難以置信的優雅,要麼是令人難以置信的慢... – sarnold

+1

...好吧,它足夠快地運行14兆字節的輸入。它必須是O(1),因此這必須是優雅的。 :D – sarnold

1

保留前一個字母的變量?第一次迭代,您只需獲取第一個字母,而不用做其他任何事情。

附錄:這個方法至少不需要浪費更多的內存,而不是浪費一個簡單的變量來存儲一個字母,沒有多餘的元組或任何東西。

3

使用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')] 

三字母也很容易:

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')] 

您可以使用元組作爲密鑰你的字典...或者更好的是使用計數器或default_dict對象做計數。祝你好運!

+1

當然,zip!不能相信我錯過了這一點。 – georg

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))]) 
+0

不錯,但是如何處理任意n-gram?我有強烈的感覺,必須有一個itertools oneliner的。 – georg

+0

@ thg435:我發佈了一般化版本 – jfs