2015-04-07 116 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 = {}'开始。 –