我是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
答案 0 :(得分:2)
添加
main()
或更正式:
if __name__ == '__main__':
main()
在源代码的末尾再次运行。
答案 1 :(得分:0)
正如flycee指出的那样,您似乎正在运行此代码。 (或者您是否只是将通话发送到main
?)
您还有其他问题...... main
的第一行:
data = {key,values}
您明确希望data
成为字典,因此逗号应为冒号:{key: values}
。
更大的问题是set / dictionary --- key
和values
---中的两个变量尚未定义。如果它被执行,这将引发UnboundLocalError
。
其他问题......
在main
中,将idx
设置为日志文件的行号(0-indexed),并将其作为mapper
参数传递给key
。 mapper
永远不会使用其key
参数,因此您可以有效地创建idx
值,只是为了扔掉它。
reducer
同样不使用其key
参数,但至少它不会完全抛弃它。尽管如此,没有理由将main
key
reducer
提供给mapper
只是为了让它保持不变。
None
返回一个""
,稍后将其用作字典中的键,否则只能使用字符串键入。要么返回一个空字符串(None
)来代替is not None
,要么---更好的是---在将其添加到字典之前确保返回值"May"
。您说您希望将"Dec"
和mapper
计算好几个月...所以不要在所有非月份中污染您的数据。
1
返回两个值的元组,其中只有一个值感兴趣。第二个值始终为1
,即使在mapper
找不到任何内容的情况下,也无法设想但 a "Jan"
....所以只需返回有趣的部分:字符串"Oct"
或sum
或其他。
如果您事先知道每个元素都是1
,那么在成千上万个元素的列表中使用len
是过度的。请改用len
。
如果事先知道列表存在 来计算某些内容,则在成千上万个元素的列表中使用int
是过度的。用一个
而是mapper
。
当Python标准库已经免费提供给你一个时,从几个不同的函数实现一个计数器是过度的。请改用collections.Counter
。
最后的狡辩:您的reducer
并未真正映射任何内容,而sum
中唯一的缩减是内置mapper
功能。那么为什么不调用month_logged
更有意义的内容,例如reducer
,并将sum
完全替换为{{1}}?