【问题标题】:Removing old elements from the time-ordered list从时间排序列表中删除旧元素
【发布时间】:2016-01-21 09:42:03
【问题描述】:

假设我有一个列表l,其中每个元素都有一个属性time,它存储一个浮点数,表示从某个基准点过去多少秒。每当发生某些事件时,我想从该列表中删除在此事件之前发生超过 T 秒的所有元素,所以目前我所做的是

l = [x in l if x.time > current_time - T]

这似乎是一种缓慢的做事方式。怎样才能更快地做到这一点?这里的元素是按时间排序的,所以我想找到第一个不满足这个条件的元素,例如

for i, x in enumerate(l):
    if x.time > current_time - T:
         break
l = l[i:]

也许有更好的方法?

【问题讨论】:

    标签: python performance list


    【解决方案1】:

    您可以使用来自collectionsdeque。它为您提供O(1) 复杂性以从列表头部删除元素。由于您的元素是按时间排序的,并且最旧的元素位于列表的头部,因此您可以轻松地逐个删除元素。

    【讨论】:

      【解决方案2】:

      由于它们是按时间排序的,因此您可以使用二进制搜索来查找截止点的索引,然后重新切片列表。二分搜索应该(大致)O(log n) 来找到截止点,然后 O(n) 来进行切片。

      但是,如果您经常这样做,最好使用双端队列并简单地弹出元素,直到头部“在保留期限内”。

      因此,任何最好的都需要进行基准测试。但是,双端队列解决方案(可能)更容易编写,因此最好从那里开始,然后在遇到性能问题时考虑其他方法。

      【讨论】:

        【解决方案3】:
        import random
        
        class Element():
        
            def __init__(self, time):
                self.time = time
        
        l = [ Element(z*5 - random.randrange(6) + 3) for z in range( 21)]
        print('list:', [z.time for z in l])
        target_time = 72
        print('cutoff time:', target_time)
        
        
        match = False
        working_list_from = 0
        working_list_to = len(l)
        while not match:
            mid = (working_list_to - working_list_from) // 2
            if l[working_list_from + mid].time < target_time:
                working_list_from += mid
            else:
                working_list_to -= mid
        
        
            match = (working_list_to - working_list_from) == 1
        
        print(' resulting list', [z.time for z in l[working_list_from+mid:]])
        

        结果:

        list: [3, 5, 9, 18, 21, 25, 32, 33, 40, 48, 49, 57, 62, 67, 73, 73, 79, 85, 93, 94, 99]
        cutoff time: 72
         resulting list [73, 73, 79, 85, 93, 94, 99]
        

        【讨论】:

          猜你喜欢
          • 2016-08-01
          • 1970-01-01
          • 2023-04-02
          • 1970-01-01
          • 2021-03-17
          • 1970-01-01
          • 2013-04-28
          • 2017-03-05
          相关资源
          最近更新 更多