我是python新手,不明白为什么这段代码不产生错误消息和输出。它读取一个web日志文件。
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
2条答案
按热度按时间fumotvh31#
添加
或更正式:
在你的源代码的最后,再次运行。
2vuwiymt2#
正如flycee所指出的,您似乎没有运行此代码(或者你只是没有把电话发到
main
?)你还有其他问题。。。第一行
main
:你显然是有意的
data
要成为字典,逗号应该是冒号:{key: values}
.更大的问题是集合/字典中的两个变量--
key
以及values
---尚未定义。这将提高UnboundLocalError
如果它被处决了。其他问题。。。
在
main
,您设置idx
到日志文件的行号(0索引),并将其传递给mapper
作为key
争论。mapper
从不使用它的key
参数,所以您可以有效地创建idx
把它扔掉。reducer
同样不使用它的key
参数,但至少它不会完全丢弃它。尽管如此,还是没有理由吃东西main
的key
至reducer
只是为了让它原封不动地回来。mapper
返回一个None
它稍后将被用作字典中的键,否则只使用字符串来设置键。返回一个空字符串(""
)代替None
,或者——更好的是——确定返回值is not None
在把它加入字典之前。你说你想数个月"May"
以及"Dec"
... 所以,不要用所有的时间来污染你的数据。mapper
返回由两个值组成的元组,其中只有一个值有意义。第二个值总是1
可以想象的是,除了一个1
... 即使是在mapper
什么也找不到。所以只需返回有趣的部分:字符串"Jan"
或者"Oct"
或者别的什么。使用
sum
如果你事先知道每一个元素都是一个元素,那么在一个数万个元素的列表上,这就太过分了1
. 使用len
相反。使用
len
在一个数万个元素的列表上,如果你事先知道这个列表的存在仅仅是为了计算一些东西,那就太过分了。使用int
相反。当python标准库已经免费为您提供了一个计数器时,从几个不同的函数实现一个计数器是过分的。使用
collections.Counter
相反。最后一句话:你的
mapper
不是真的Map任何东西,而且reducer
是内置的吗sum
功能。那为什么不打电话呢mapper
一些更有意义的事情,比如month_logged
,并替换reducer
完全sum
?