【Python】List多级列表场景计算算法及实现分享

116 篇文章 15 订阅
22 篇文章 0 订阅

最近项目组有个50万行的数据需要处理,看着都头大,想了半天,代码实现1小时才完成,特别分享出来给小伙伴看看,有更好想法的欢迎提出优化,为了方便展示只截取了部分数据

a = [[
305,
“144926190”,
“ENTER_mdwsw_wsw_3”,
“”
],
[
306,
“144927044”,
“LEAVE_mdwsw_wsw_3”,
“”
],
[
313,
“144937095”,
“ENTER_mdwsw_wsw_2”,
“”
],
[
303,
“144938371”,
“ENTER_mdwsw_wsw_1”,
“”
],
[
304,
“144938454”,
“LEAVE_mdwsw_wsw_1”,
“”
],
[
314,
“144938529”,
“LEAVE_mdwsw_wsw_2”,
“”
]]

数据说明:
1.列表a是一个不限长度列表;
2.子列表:
第一项是id;
第二项是时间戳;
第三项是方法与事件,方法是第一个_之前的部分,共两类:ENTER与LEAVE,事件是第一个_之后的部分;
第四项是对应事件的LEAVE与ENTER时间之差,目前为空的是待计算的;

计算规则:

1.从第一个子列表开始,找到事件相同,方法不同的计算时间差,更新到LEAVE事件的第四个元素;
2.中间如果还有事件,同样计算同名事件的时间差,并将其赋给LEAVE事件的第四个元素,同时这个时间还要用开头事件时间差再去除这部分;
3.同一个事件中间的列表不一定是固定的;
4.同一个事件如果ENTER与LEAVE之间还有其他事件的ENTER与LEAVE,在计算的时候也要去除时间差;
5.还需要考虑两个子列表的id相差是否为1,若为1,则是相邻的事件,若不是1,则存在嵌套事件;

计算场景:
1.相邻型
数据:a = [
[
305,
“144926190”,
“ENTER_mdwsw_wsw_3”,
“”
],
[
306,
“144927044”,
“LEAVE_mdwsw_wsw_3”,
“”
]
]

只需填充id=306的第四个元素,计算方式:144927044-144926190=854
更新:
[
306,
“144927044”,
“LEAVE_mdwsw_wsw_3”,
854
]

2.嵌套型
数据 a= [[
313,
“144937095”,
“ENTER_mdwsw_wsw_2”,
“”
],
[
303,
“144938371”,
“ENTER_mdwsw_wsw_1”,
“”
],
[
304,
“144938454”,
“LEAVE_mdwsw_wsw_1”,
“”
],
[
314,
“144938529”,
“LEAVE_mdwsw_wsw_2”,
“”
]]
此时需要计算的是两次LEAVE_事件的耗时,由于存在嵌套,需要分三步计算:
第一步:先计算313、314,这一组:144938529-144937095 = 1434,此时数据还不能直接更新在314上,因为,中间涉及嵌套耗时;
第二步:再计算303、304,这一组:144938454-144938371 = 83, 此时可以将83更新到数据304上,即:
[
304,
“144938454”,
“LEAVE_mdwsw_wsw_1”,
83
]
第三步:计算最终314数据:1434-83 = 1351, 更新数据到314:
[
314,
“144938529”,
“LEAVE_mdwsw_wsw_2”,
1351
]
这样就算完成计算过程,中间如果涉及多层嵌套依旧如此计算;

思路:
(())()()(()()) 算法题:括号有效性的延伸

代码:

a = [
    [305, "144926194", "ENTER_Can_Interrupt_CANFD00_Cat2", ""],
    [306, "144927048", "LEAVE_Can_Interrupt_CANFD00_Cat2", ""],
    [313, "144937099", "ENTER_Spi_Interrupt_SCB5_Cat2", ""],
    [303, "144938375", "ENTER_SpiSeqEndNotification_SBC", ""],
    [304, "144938458", "LEAVE_SpiSeqEndNotification_SBC", ""],
    [314, "144938533", "LEAVE_Spi_Interrupt_SCB5_Cat2", ""]
]


# 定义类:实现堆栈的,pop,push,is_empty,is_full功能
class Stack:
    def __init__(self):
        self.stack = []
        self.time_list = []

    def push(self, item):
        if self.is_empty():
            # print("push item:", item)
            self.stack.append(item)
        else:
            # print("888"*8)
            # 获取栈尾
            last = self.stack[-1]
            method_last, event_last = last[2].split("_", 1)
            method_item, event_item = item[2].split("_", 1)
            # print("1111", method_last, event_last)
            # 如果栈尾元素与待出栈元素相同,则出栈
            if event_last == event_item:
                # 计算一个时间变量
                time_diff = int(item[1]) - int(last[1])
                if self.time_list:
                    time_diff -= self.time_list[-1]
                item[3] = time_diff
                # print("3333", time_diff)
                print("2222", item)
                # 这个时间变量存储到time_list
                self.stack.pop()
                if not self.is_empty():
                    self.time_list.append(time_diff)


            # 如果栈尾元素与待出栈元素不同,则入栈
            else:
                # print("push item:", item)
                self.stack.append(item)
        # print("xxxxxx",self.time_list)


    def pop(self, item):
        if not self.is_empty():
                return self.stack.pop()

    def is_empty(self):
        return len(self.stack) == 0

    def is_full(self):
        return len(self.stack) == 10


if __name__ == '__main__':
    s = Stack()

    for i in a:
        s.push(i)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔都吴所谓

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值