【问题标题】:Remove items from list if they are within a given range如果它们在给定范围内,则从列表中删除它们
【发布时间】:2014-07-17 16:00:06
【问题描述】:

我想从排序列表中删除每个项目,前提是它距离之前的事件之一在 100 秒内。示例:

event_list = [3, 10, 12, 140, 140, 150, 300]
filtered_event_list = [3, 140, 300]

我有以下似乎可以工作的代码。但它不会删除与前一个具有相同时间的项目。我遇到的另一个问题是它不是非常pythonic,因为在开始删除 100 秒内的项目之前,我需要一个额外的占位符来表示真/假或 0/1 来存储我的结果。

downCycles = 100
event_list = [[3, 0], [10, 0], [12, 0], [140, 0], [140, 0], [150, 0], [300, 0]]

for e_idx, event in enumerate(event_list):

if e_idx > 0:

    prev_idx = e_idx - 1

    while event[0] - event_list[prev_idx][0] < downCycles and prev_idx >= 0:

        event[1]  = event[0] - event_list[prev_idx][0]
        prev_idx -= 1

filtered_event_list = [e for e in event_list if e[1] == 0]
# filtered_event_list = [[3, 0], [140, 0], [140, 0], [300, 0], [800, 0]]

有人知道在这个例子中删除第二个 140 吗? 有没有人更好的方法来编写这段代码?

谢谢 问候 迈克尔

【问题讨论】:

    标签: python list python-2.7 optimization


    【解决方案1】:
    from itertools import tee
    
    downCycles = 100
    event_list = [3, 10, 12, 140, 140, 150, 300]
    left, right = tee(event_list)
    [next(right)] + [i for i in right if i > next(left) + downCycles]
    

    输出:

    [3, 140, 300]
    

    【讨论】:

      【解决方案2】:

      你可以试试这个。只是尝试检查第一个元素与下一个元素的区别

      event_list = [3, 10, 12, 140, 140, 150, 300]
      new_list=[event_list[0]]+
      
      for element in event_list[1:]:
          if abs(new_list[-1]-element)>=100:
             new_list.append(element)
      print new_list
      

      如果你想制作通用方法,请参阅下面的答案

      def elapsed_list(items,time):
          new_list=[items[0]]
      
          for element in items[1:]:
              if abs(new_list[-1]-element)>=time:
                 new_list.append(element)
          return new_list
      
      
      print elapsed_list(event_list,10)
      #output [3, 140, 150, 300]
      
      print elapsed_list(event_list,100)
      #output [3, 140, 300]
      
      print elapsed_list(event_list,200)
      #output [3, 300]
      

      解释我是怎么做到的

      1. 我们需要在第一个元素和下一个元素之间获取差异的逻辑
      2. 所以我采用了另一个列表,该列表采用第一个元素,如果差异大于 100,则计算差异。将其附加到 new_list
      3. 现在执行与new_list[-1] 获取的新附加元素相同

      【讨论】:

        【解决方案3】:

        这将返回一个包含项目的生成器。

        def removeCloseItems(items, itemDistance):
            if items:
                lastOutput = items[0]
                yield items[0]
                for currentItem in items[1:]:
                    if ((currentItem - lastOutput) > itemDistance):
                        lastOutput = currentItem
                        yield currentItem
        

        示例用法:

        In [79]: [x for x in removeCloseItems ([3, 10, 12, 140, 140, 150, 300], 100)]
        Out[79]: [3, 140, 300]
        

        这假设当您说“距前面的一项 100 以内”时,您的意思是前面的 输出 项之一。输出应该是什么:

        [x for x in removeCloseItems([1, 100, 102], 100)
        

        你想要[1, 102],还是[1]

        后者将使用以下代码生成:

        def removeCloseItems(items, howFar):
            if items:
                lastItem = items[0]
                yield items[0]
                for currentItem in items[1:]:
                    lastItem = currentItem
                    if ((currentItem - lastItem) > howFar):
                        yield currentItem
        

        【讨论】:

        • 谢谢zck。您的选项一正是我想要的。还要感谢选项 2,这也很有用。迈克尔
        【解决方案4】:

        一种方法是:

        event_list = [3, 10, 12, 140, 140, 150, 300]    
        filtered_lst = [event_list[0]]
        filtered_lst +=  [j for (i, j) in zip(event_list[:-1], event_list[1:]) if j-i >100]
        

        现在

        filtered_lst == [3, 140, 300]
        

        【讨论】:

          猜你喜欢
          • 2020-12-30
          • 1970-01-01
          • 2021-12-13
          • 1970-01-01
          • 1970-01-01
          • 2020-04-18
          • 2011-05-19
          • 2021-06-26
          • 1970-01-01
          相关资源
          最近更新 更多