改变我的代码输出 - Python

时间:2016-11-15 05:02:47

标签: python

我想更改代码的输出。我有这样的代码:

from collections import defaultdict

third = defaultdict(lambda: (defaultdict(lambda : defaultdict(int))))

count = 0

fh = open("C:/Users/mycomp/desktop/data.txt", "r").readlines()

for line in fh:
    line_split = line.split();

    date = line_split[0];
    time = line_split[1];
    ip = line_split[2];

    third [date][time][ip]+= 1

for date, d in third.iteritems():
     for time , count in d.iteritems():
         print "%s %s %s %s" % (date, time, count,ip)

这样的日志文件:

2016-11-04 00:00:12 10.11.13.13 
2016-11-05 00:00:15 10.14.12.11 
2016-11-06 00:00:19 10.10.15.13 

我的输出如下。

2016-10-04 07:46 defaultdict(<type 'int'>, {'10.11.13.15': 574}) 10.11.13.15
2016-10-04 15:58 defaultdict(<type 'int'>, {'10.21.24.13': 364}) 10.21.24.13
2016-10-04 15:59 defaultdict(<type 'int'>, {'10.21.22.13': 359}) 10.21.22.13
2016-10-04 07:42 defaultdict(<type 'int'>, {'10.21.27.10': 287}) 10.21.27.10
2016-10-04 07:43 defaultdict(<type 'int'>, {'10.11.37.13': 337}) 10.11.37.13

但是我想要这样的输出:

2016-10-04 07:46 {'10.11.13.15': 574}) 10.11.13.15
2016-10-04 15:58 {'10.21.24.13': 364}) 10.21.24.13
2016-10-04 15:59 {'10.21.22.13': 359}) 10.21.22.13
2016-10-04 07:42 {'10.21.27.10': 287}) 10.21.27.10
2016-10-04 07:43 {'10.11.37.13': 337}) 10.11.37.13

1 个答案:

答案 0 :(得分:1)

您的词典有三个级别,因此每个值都需要三个键(日期,时间和IP)。你的输出代码在前两个循环,但是没有IP循环,所以你得到一个字典。

我怀疑你想要这样的东西,有三个循环:

for date, x in third.iteritems():
    for time, y in x.iteritems():
        for ip, count in y.itertiems():
            print "%s %s %s %s" % (date, time, count, ip)

如果你真的希望单个日期和时间的所有数据都打印在一行上(即使涉及多个IP),我想,你可以改变你的print声明,它看起来更好。您在当前代码中获得的count值是从IP地址映射到count的最内层defaultdict之一。如果需要,您可以将其转换为常规dict并将其包含在print来电中:

for date, d in third.iteritems():
    for time, ip_count in d.iteritems():
        print "%s %s %s" % (date, time, dict(ip_count))

请注意,只有三种格式化(IP和计数是同一对象的一部分)。您的代码中的ip参数实际上并没有正常工作,因为它没有在您的两个循环级别中设置。实际上,您打印出填写字典时使用的最后一个IP地址(因此输入文件最后一行的IP地址)。与您的示例输出不同,我怀疑它与您打印的内部字典的内容不匹配。

请注意,上述代码的两个版本都会以大多数任意顺序打印您的数据。同一天的所有行将一起打印(并且所有行在一天内同时打印),但在这些分组之外,值将按任意顺序排列。您可能希望使用sorted将数据置于有用的顺序中:

import operator
keyfunc = operator.itemgetter(0)

for date, x in sorted(third.iteritems(), key=keyfunc):
    for time, y in sorted(x.iteritems(), key=keyfunc):
        for ip, count in sorted(y.itertiems(), key=keyfunc):
            print "%s %s %s %s" % (date, time, count, ip)

我还考虑使用嵌套较少的数据结构,例如用date, time, ip元组键入的字典。