字典中的棘手列表操作

Posted

技术标签:

【中文标题】字典中的棘手列表操作【英文标题】:Tricky list manipulation inside a dictionary 【发布时间】:2016-04-21 07:10:31 【问题描述】:

我在一个文件中有以下数据。我想从相关行中提取timesize 并绘制时间序列图。

    03/12 20:23:26.11: 04:23:26 L9 <Mx  Acc  Magnum All            XDV:00111A0000000117 00D3001200870172 01FF6000F01CFE81 3D26000000000300
    03/12 20:23:26.11: 04:23:26 L9 <Mx  Acc  MID 0x1500 Len 26   XDV:00111A0000000117 00D3001200870172 01FF6000F01CFE81 3D26000000000300
    03/12 20:23:26.11: 04:23:26 L8 <Mx  JK31 (Mx)                  JSP:17.37.6.99: Size = 166, Data: 00345C4101003031 E463EF0113108701 5A01FF6008F01CFE 81AB170000000003 EF01131087015A01 FF6008F01CFE81AB 170000000003EF01 131087015B01FF60 00F01CFE81701B00 00000003EF011310 87015B01FF6000F0 1CFE81701B000000 0003EF0113108701 5C01FF2000F01CFE 81CB240000000003 EF01131087015C01 57CC00F01CFE81CB 240000000003EF01 131087015D01FF20 00F01CFE815B2900 00000003EF011310 87015D01FF2000F0 1CFE815B29000000 0003EF0113108701 5E01FF6000F01CFE 819D280000000003 EF01131087015E01 FF6000F01CFE819D 0003
    03/15 20:23:26.11: 04:23:26 L8 <Kx  JK31 (Kx)                  JSP:15.33.2.93: Size = 163, Data: 00647741000030EF 01131087015A01FF 6008F01CFE81AB17 0000000003EF0113 1087015A01FF6008 F01CFE81AB170000 000003EF01131087 015B01FF6000F01C FE81701B00000000 03EF01131087015B 01FF6000F01CFE81 701B0000000003EF 01131087015C01FF 2000F01CFE81CB24 0000000003EF0113 1087015C01FF2000 F01CFE81CB240000 000003EF01131087 015D01FF2000F01C FE815B2900000000 03EF01131087015D 01FF2000F01CFE81 5B290000000003EF 01131087015E01FF 6000F01CFE819D28 0000000003EF0113 1087015E01FF6000 F01CFE819D280000 A6220000000003
    03/15 20:23:26.11: 04:23:26 L9 <Kx  JK31 (Kx)                  JSP:10.22.1.53:Size = 163, Data: 009D1141000030EF 01131087015A01FF 6008F01CFE81AB17 0000000003EF0113 1087015A01FF6008 F01CFE81AB170000 000003EF01131087 015B01FF6000F01C FE81701B00000000 03EF01131087015B 01FF6000F01CFE81 701B0000000003EF 01131087015C01FF 2000F01CFE81CB24 0000000003EF0113 1087015C01FF2000 F01CFE81CB240000 000003EF01131087 015D01FF2000F01C FE815B2900000000 03EF01131087015D 01FF2000F01CFE81 5B290000000003EF 01131087015E01FF 6000F01CFE819D28 0000000003EF0113 1087015E01FF6000 F01CFE819D280000 A6220000000003

我有以下程序来做。

from dateutil import parser

import matplotlib.pyplot as plt

match_list = ["L8 <Mx JK31 (Mx)", "L9 <Mx JK31 (Mx)"]  ## put all match strings in this list
with open("test.txt") as fin:
    print(' : ', fin.name)
    time_data =   ## save data in dictionaries, with string keys and lists as values
    size_data = 
    for line in fin:
        for match in match_list:
            if match in line:
               if match not in time_data:
                   time_data[match] = []  ## initialize empty list the first time this key is encountered
                   size_data[match] = []
               line = line.strip.split()
               time_str = line[2]
               t = parser.parse(time_str)  
               time_data[match].append(t)
               size = int(line[9].strip(","))
               size_data[match].append(size)


    for match in match_list:
        plt.figure()  ## create a new figure for each data set
        plt.plot(time_data[match], size_data[match])
    plot.show()  ## simultaneously show all plots

我使用上面的两个字典,time_datasize_data。每个数据都包含match_list 的元素作为它们的键。 values 是一个包含日期时间对象的列表。

上述操作是为了便于使用 matplotlib 进行绘图。 现在我想做以下事情。

您可以在上面的示例数据中看到相同键 L8 &lt;Mx JK31 (Mx) 的两个值具有相同的时间 (04:23:26)。

我想修改数据结构(即我的字典中的列表),以便我希望每分钟汇总一次大小值(即字典 size_data 中的列表中的值)。

假设有以下 5 个值

04:23:26 56 04:23:26 60 04:23:43 70 04:23:46 80 04:23:56 90

我希望将以上内容替换为 04:23:00356。我该怎么做。

【问题讨论】:

文件是否仅包含制表符分隔值?如果是这样,请使用csv 模块。 @ReutSharabani - 我不这么认为。它似乎包含空格。 值内部有空格,但有什么区别? @ReutSharabani - 我不确定。如何检查? 看这个:***.com/questions/767545/… 【参考方案1】:

我相信您的问题比起初看起来要容易一些,因为解析文件的额外开销。我假设解析有效,你最终得到一个列表元组,字典...... 现在您想对该列表执行某种聚合,对吗?

所以,从

开始
[
['10:10:01', 45],
['10:10:11', 135],
['10:10:50', 21],
['10:10:57', 4],
['10:11:01', 2],
['10:11:11', 8]
]

你想得到

[
['10:10:00', 205],
['10:11:00' 10]
]

如果是这样,您可以轻松地为此使用 defaultdict 和 datetime.replace(seconds=0)。

此代码不是即插即用的,但您应该能够很容易地适应您的情况

input = # your parser function
output = defaultdict(int)

for date, value in input.items():
  output[date.replace(seconds=0)] += value

如果您想再次列出列表,可以使用output.items()

祝你好运!

【讨论】:

我的清单不是这样的。我的意思是,我在两个字典中有两个单独的列表。它们通过一个共同的key 相关联

以上是关于字典中的棘手列表操作的主要内容,如果未能解决你的问题,请参考以下文章

Python 02--列表字典集合

python-基础 列表 集合 字典

Python列表,字典,元组,字符串操作

Python基础2 列表字典集合

redis之列表字典操作

ptyhon的列表与字典操作