2015-04-07 83 views
0

我是python的新手,無法弄清楚爲什麼這段代碼不會產生錯誤消息,也沒有輸出。它讀取一個網絡日誌文件。Python映射器reducer

def mapper(key, line): 
    parts = line.split("/") 
    if len(parts) > 2: 
     return parts[1], 1 
    return None, 1 

def reducer(key, values): 
    return key, sum(values) 

def main(): 
    data = {key,values} 
    with open('apache.log', 'r') as logfile: 
     for idx, line in enumerate(logfile): 
      line = line.strip() 
      key, val = mapper(idx, line) 
      if key in data: 
       data[key].append(val) 
      else: 
       data[key] = [val,] 
     for key, values in data.items(): 
      print reducer(key, values) 

日誌文件:

[31/Dec/1994:23:46:48 -0700] "GET 116.gif HTTP/1.0" 200 12053 
remote - - [31/Dec/1994:23:50:42 -0700] "GET 2196.ps HTTP/1.0" 200 73941 
remote - - [31/Dec/1994:23:55:08 -0700] "GET 45.html HTTP/1.0" 200 5489 
remote - - [31/Dec/1994:23:56:55 -0700] "GET 2195.ps HTTP/1.0" 200 522318 
remote - - [31/Dec/1994:23:59:37 -0700] "GET 957.ps HTTP/1.0" 200 122146 
remote - - [01/Jan/1995:00:31:54 -0700] "GET index.html HTTP/1.0" 200 2797 
remote - - [01/Jan/1995:00:31:58 -0700] "GET 2.gif HTTP/1.0" 200 2555 
+0

你想在日誌文件???找什麼,什麼是烏拉圭回合的期望輸出 – Hackaholic

+0

Web服務器命中結果: ( '月',43666) ( '月',72114) ( '月',99761 ) ('Apr',65011) – user4745212

回答

2

添加

main() 

或更正式的:

if __name__ == '__main__': 
    main() 

在你的源代碼的結尾,並再次運行。

+0

這不提供問題的答案。要批評或要求作者澄清,請在其帖子下方留言。 – Signare

+0

@Signare:這實際上是_does_回答「爲什麼這段代碼沒有產生錯誤信息,也沒有輸出」---它從來沒有運行過。如果是這樣,@ user4745212會問我們爲什麼他得到一個'SyntaxError'或者一個'UnboundLocalError'。 –

+0

@Signare:我收回了'SyntaxError'聲明 - 它來自我的舊Python 2.6安裝。 '{key,values}'在3.x和2.7中是合法的......雖然它是一個集合,而不是他想要的字典。 –

0

由於flycee已經指出,你看起來並不是這個代碼運行的是。 (還是你只是沒有張貼調用main?)

您有其他問題...的main第一行:

data = {key,values} 

你顯然是data是一個字典,所以應該用逗號冒號:{key: values}

更大的問題是集合/字典中的兩個變量--- keyvalues ---尚未定義。如果它被執行過,將會引發一個UnboundLocalError

其他問題...

  • main,設置idx到日誌文件中的行數(0-索引),並將它傳遞給mapperkey參數。 mapper從來沒有使用它的key參數,所以你有效地創造idx值只是爲了扔掉它。

  • reducer同樣不使用它的key參數,但至少它不會完全拋棄它。儘管如此,沒有理由將mainkey改爲reducer,以便恢復原狀。

  • mapper返回一個None,稍後將被用作字典中的一個鍵,否則該字典僅用字符串鍵入。或者返回一個空字符串("")代替None,或者更好的是在將其添加到字典之前確保返回值爲is not None。你說過你要計算幾個月,比如"May""Dec" ......所以不要用所有的非月份來污染你的數據。

  • mapper返回一個包含兩個值的元組,其中只有一個值是任意的。第二個值總是1,並且不可能是任何東西但是 a 1 ......即使在mapper什麼也沒有找到的情況下。所以只需返回有趣的部分:字符串"Jan""Oct"或其他。

  • 如果您事先知道每個元素都是1,則在成千上萬個元素的列表上使用sum會過度殺傷。改爲使用len

  • 使用len在成千上萬的元素的列表是過度殺傷,當你事先知道該列表存在完全來計數的東西。改爲使用 int

  • 當Python標準庫已經免費爲您提供一個函數時,從幾個不同的函數實現一個計數器是矯枉過正的。改爲使用collections.Counter

最後一個詭辯:你mapper是不是真的任何映射,並且只有在你reducer減少是內置sum功能。那麼爲什麼不打電話mapper更有意義的東西,如month_logged,並用sum完全取代reducer

+0

我沒有寫代碼。此代碼旨在演示使用python的hadoop map reduce概念。這是ipython筆記本的錯誤消息,如果數據{key value}:UnboundLocalError Traceback(最近調用最後一次) in () 20 for key,data.items() : 21 print reducer(key,values) ---> 22 main() 使用python運行代碼2.7 ----- ----------如果你有更好的解決方案,請發佈它因爲我只是python的初學者。謝謝。 – user4745212

+0

@ user4745212:那'UnboundLocalError'正是我說你會在這一行上得到的錯誤:你在嘗試在定義之前使用'key'和'values'變量。那將是任何地方的錯誤。由於您將隨時添加想要的字典數據,因此使用任何內容初始化數據似乎都很愚蠢 - 而不是以'data = {}'開始。 –