2011-11-23 47 views

回答

0
from collections import defaultdict 

def main(separator='\t'): 
    data = read_mapper_output(sys.stdin, separator=separator) 
    counts = defaultdict(lambda: [0, 0]) 
    for word, (count1, count2) in data: 
     values = counts[word] 
     values[0] += count1 
     values[1] += count2 

    for word, (count1, count2) in counts.iteritems(): 
     print('{0}\t{1}\t{2}'.format(word, count1, count2)) 
+0

這當然是一種有效的方法,但我的印象是,OP想要真正理解函數式編程模式和習慣用法。 –

2

GROUPBY

即從itertools模塊groupby功能,記錄heredata根據將itemgetter(0)(來自operator模塊的itemgetter類的實例,記錄爲here)應用到每個元素的結果「分組」。它返回(關鍵結果,帶有該關鍵字的迭代器元素)對。因此,每次通過循環時,current_word是一行data行(索引-0,即第一項,由itemgetter提取)共有的「單詞」,groupdata行上的迭代器,它們開始與那word。如您的代碼文檔中所述,文件的每一行都有兩個單詞:一個實際的「單詞」和一個計數(文本旨在解釋爲一個數字)

sum(int(count)for current_word ,計數在基)

意味着正是它說:所述count的整數值的總和,對於每個(current_wordcount)一對在group找到。如上所述,每個group是來自data的一組線。因此,我們採用所有以current_word開頭的行,將其字符串count的值轉換爲整數,然後將它們相加。

我該如何修改這個塊,使它基本上繼續做它現在做的事情,但有第二個計數器值?即輸入是(word,count1,count2),輸出是(word,count1,count2)。

那麼,您希望每個計數代表什麼,以及您希望數據來自哪裏?

我打算採取我認爲的認爲是最簡單的解釋:您要修改數據文件以在每一行上有三個項目,並且您將從每列的號碼分開。

groupby將會是相同的,因爲我們仍然按照相同的方式對線條進行分組,我們仍然按照「單詞」對它們進行分組。

sum部分將需要計算兩個值:第一列數字的總和和第二列數字的總和。

當我們遍歷group時,我們會得到三個值的集合,所以我們想將它們解壓爲三個值:例如current_word, group_a, group_b。對於其中的每一個,我們希望將整數轉換應用於每行上的兩個數字。這給了我們一串數字的序列;如果我們想要添加所有的第一個數字和所有的第二個數字,那麼我們應該製作一對數字序列。爲此,我們可以使用另一個itertools函數,稱爲izip。然後,我們可以分別對這些數據進行求和,將它們再次解包爲兩個單獨的數字序列變量並對它們進行求和。

這樣:

counts_a, counts_b = izip(
    (int(count_a), int(count_b)) for current_word, count_a, count_b in group 
) 
total_a, total_b = sum(counts_a), sum(counts_b) 

或者我們可以只讓一對 - 的 - 數做相同的(X對於z Y)再次招:

totals = (
    sum(counts) 
    for counts in izip(
     (int(count_a), int(count_b)) for current_word, count_a, count_b in group 
    ) 
) 

雖然這一結果將是在打印聲明中使用有點困難:)

+0

如果你指定了它失敗的原因,它會幫助我找出錯誤。 –

+0

以上是非常有用的,但是沒有任何代碼片段真正適用於我的情況。 我編輯了我的帖子以包含更新的代碼+輸出。有任何想法嗎? –