Python 映射器减速器
Python mapper reducer
我是 python 的新手,不明白为什么这段代码没有产生错误消息和输出。它读取网络日志文件。
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
添加
main()
或更正式:
if __name__ == '__main__':
main()
在源代码的末尾,然后再次 运行。
正如 flycee 所指出的,您似乎不是 运行 这段代码。 (或者你只是没有 post 调用 main
?)
你还有其他问题...main
第一行:
data = {key,values}
您显然希望 data
成为字典,因此逗号应该是冒号:{key: values}
.
一个更大的问题是集合/字典中的两个变量--- key
和values
--- 还没有被定义。如果它被执行,这将引发 UnboundLocalError
。
其他问题...
在 main
中,您将 idx
设置为日志文件的行号(从 0 开始索引),并将其作为 [=15] 传递给 mapper
=] 参数。 mapper
从不 使用 其 key
参数,因此您实际上是在创建 idx
值只是为了将其丢弃。
reducer
同样没有使用它的 key
参数,但至少它没有完全丢弃它。不过,没有理由将 main
的 key
喂给 reducer
只是为了让它保持不变。
mapper
returns a None
稍后将用作字典中的键,否则仅使用字符串作为键。 return 一个空字符串 (""
) 代替 None
,或者 --- 更好的是 --- 确保 return 值 is not None
之前将其添加到字典中。你说你想计算像 "May"
和 "Dec"
这样的月份...所以不要用所有非月份污染你的数据。
mapper
returns 是两个值的元组,只有其中一个值是有用的。第二个值始终是 1
,并且不可能是任何东西 但 是 1
... 即使在 mapper
什么也找不到的情况下.所以只是 return 有趣的部分:字符串 "Jan"
或 "Oct"
或其他。
当您事先知道每个元素都是 1
时,在包含数万个元素的列表上使用 sum
就有点过分了。请改用 len
。
当您事先知道该列表存在时,
在包含数万个元素的列表上使用 len
就有点矫枉过正了 只是 来计算一些东西.使用一个
int
代替。
当 Python 标准库已经免费为您提供一个计数器时,从几个不同的函数中实现一个计数器就太过分了。请改用 collections.Counter
。
最后的狡辩:您的 mapper
并没有真正映射任何东西,您的 reducer
中唯一减少的是内置的 sum
函数。那么为什么不调用 mapper
更有意义的东西,比如 month_logged
,并将 reducer
完全替换为 sum
?
我是 python 的新手,不明白为什么这段代码没有产生错误消息和输出。它读取网络日志文件。
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
添加
main()
或更正式:
if __name__ == '__main__':
main()
在源代码的末尾,然后再次 运行。
正如 flycee 所指出的,您似乎不是 运行 这段代码。 (或者你只是没有 post 调用 main
?)
你还有其他问题...main
第一行:
data = {key,values}
您显然希望 data
成为字典,因此逗号应该是冒号:{key: values}
.
一个更大的问题是集合/字典中的两个变量--- key
和values
--- 还没有被定义。如果它被执行,这将引发 UnboundLocalError
。
其他问题...
在
main
中,您将idx
设置为日志文件的行号(从 0 开始索引),并将其作为 [=15] 传递给mapper
=] 参数。mapper
从不 使用 其key
参数,因此您实际上是在创建idx
值只是为了将其丢弃。reducer
同样没有使用它的key
参数,但至少它没有完全丢弃它。不过,没有理由将main
的key
喂给reducer
只是为了让它保持不变。mapper
returns aNone
稍后将用作字典中的键,否则仅使用字符串作为键。 return 一个空字符串 (""
) 代替None
,或者 --- 更好的是 --- 确保 return 值is not None
之前将其添加到字典中。你说你想计算像"May"
和"Dec"
这样的月份...所以不要用所有非月份污染你的数据。mapper
returns 是两个值的元组,只有其中一个值是有用的。第二个值始终是1
,并且不可能是任何东西 但 是1
... 即使在mapper
什么也找不到的情况下.所以只是 return 有趣的部分:字符串"Jan"
或"Oct"
或其他。当您事先知道每个元素都是
1
时,在包含数万个元素的列表上使用sum
就有点过分了。请改用len
。当您事先知道该列表存在时,
在包含数万个元素的列表上使用
len
就有点矫枉过正了 只是 来计算一些东西.使用一个int
代替。当 Python 标准库已经免费为您提供一个计数器时,从几个不同的函数中实现一个计数器就太过分了。请改用
collections.Counter
。
最后的狡辩:您的 mapper
并没有真正映射任何东西,您的 reducer
中唯一减少的是内置的 sum
函数。那么为什么不调用 mapper
更有意义的东西,比如 month_logged
,并将 reducer
完全替换为 sum
?