计算字典中唯一项的数量

时间:2013-07-17 17:41:32

标签: python

我的程序读入一个大型日志文件。然后它在文件中搜索IP和TIME(括号中的任何内容)。

5.63.145.71 - - [30 / Jun / 2013:08:04:46 -0500]“HEAD / HTTP / 1.1”200 - “ - ”“checks.panopta.com” 5.63.145.71 - - [30 / Jun / 2013:08:04:49 -0500]“HEAD / HTTP / 1.1”200 - “ - ”“checks.panopta.com” 5.63.145.71 - - [30 / Jun / 2013:08:04:51 -0500]“HEAD / HTTP / 1.1”200 - “ - ”“checks.panopta.com”

我想阅读整个文件,并按如下方式汇总条目:

Num 3 IP 5.63.145.1 TIME [30 / Jun / 2013:08:04:46 -0500]条目数,IP,时间和日期

到目前为止我所拥有的:

import re


x = open("logssss.txt")

dic={}


for line in x:
    m = re.search(r"\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b",line).group().split()
    c = re.search(r"\[(.+)\]",line).group().split()
    for i in range(len(m)):
        try:
            dic[m[i]] += 1 
        except:
            dic[m[i]] = 1
        k = dic.keys()
for i in range(len(k)):
    print dic[k[i]], k[i]

上面的代码现在正确显示!感谢。

6 199.21.99.83

1 5.63.145.71

编辑:那么现在如何将c添加到我的输出中,时间戳明显不同,但只是在同一行上获取其中一个值是可能的?

2 个答案:

答案 0 :(得分:3)

将print语句移出主循环

import re
x = open("logssss.txt")

dic={}


for line in x:
    m = re.search(r"\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b",line).group().split()
    c = re.search(r"\[(.+)\]",line).group().split()
    for i in range(len(m)):
        try:
            dic[m[i]] += 1 
        except:
            dic[m[i]] = 1

for k,v in dic.iteritems(): #or items if Python 3.X
    print k, v 

作为提示,你可以利用pythons Counter类替换你的try除了块

from collections import Counter
dic = Counter()
for line in x:
    m = re.search(r"\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b",line).group().split()
    c = re.search(r"\[(.+)\]",line).group().split()
    for i in range(len(m)):
        dic[m[i]] += 1

for k,v in dic.iteritems(): #or items if Python 3.X
    print k, v   

从您的评论中,我只会使用列表字典,每个IP地址的计数可以从列表的长度中提取:

dic = {}
for line in x:
    m = re.search(r"\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b",line).group().split()
    c = re.search(r"\[(.+)\]",line).group().split()
    for i in range(len(m)):
        dic.setdefault(m[i], []).append(c)

for k,v in dic.iteritems(): #or items if Python 3.X
    print k, len(v), v 

答案 1 :(得分:2)

您可以使用效率更高的Counter

from collections import Counter
cnt = Counter()
for line in x:
    m = re.search(r"\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b",line).group().split()
    cnt.update(m)

然后在主循环外完成打印:

for k,v in cnt.iteritems():
    print k, v

要包含c,defaultdict会更合适:

dict = defaultdict(list)
for line in x:
    m = re.search(r"\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b",line).group().split()[0]
    c = re.search(r"\[(.+)\]",line).group().split()[0]
    dict[m].append(c)

for k,v in dict.iteritems():
    print k, len(v), v

我的理解是每行只有1个ip和日期,因此[0]采取第一个也是唯一的出现。