Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:在遍历列表时从列表中删除元素,这是查找范围内值的最有效方法_Python_Database_Algorithm_List - Fatal编程技术网

Python:在遍历列表时从列表中删除元素,这是查找范围内值的最有效方法

Python:在遍历列表时从列表中删除元素,这是查找范围内值的最有效方法,python,database,algorithm,list,Python,Database,Algorithm,List,我有一些非常大的元组列表,这些元组来自包含id、开始时间和结束时间的数据库 我也有一个定期间隔的时间列表,这些都是datetime对象 我基本上需要遍历这些时间,找到所有时间在其范围内的元组 我想知道最有效的方法是什么。我想到的第一个想法是这样的伪代码: for time in times: for tuple in tuples: if tuple.start_time <= time <= tuple.end_time: # add

我有一些非常大的元组列表,这些元组来自包含id、开始时间和结束时间的数据库

我也有一个定期间隔的时间列表,这些都是datetime对象

我基本上需要遍历这些时间,找到所有时间在其范围内的元组

我想知道最有效的方法是什么。我想到的第一个想法是这样的伪代码:

for time in times:
    for tuple in tuples:
        if tuple.start_time <= time <= tuple.end_time:
            # add tuple to some_other_list
        if tuple.end_time < time
            # remove tuple from tuples
时间列表将存储在一个生成器中,因此循环通过它们将产生如下结果:

2017-12-15 00:00:00
2017-12-22 00:00:00
2017-12-29 00:00:00
2018-01-05 00:00:00
2018-01-12 00:00:00
2018-01-19 00:00:00
我对实际的输出是相当不可知的,它只是一本字典

{'2017-12-15 00:00:00': [list of matching ids], '2017-12-22 00:00:00': [list of matching ids], ...}

任何想法或建议将不胜感激

首先,关于删除不相关的间隔的注意事项:如果从一个长列表中删除,性能将非常糟糕,因为需要将后面的元素移到空白中。可以通过用一个整数替换已删除的元素来解决这个问题,该整数表示要跳多远才能找到下一个真实数据

这是典型的区间查询问题,通常的答案是or树。但是,如果可以一次存储所有结果,从而存储所有已排序的查询时间,则可以使用一个简单的替代方法:不是迭代时间,然后搜索时间间隔,而是在所有时间间隔上迭代一次,然后执行二进制搜索,以查找每个时间间隔包含的最早和最新查询时间。然后将间隔的ID附加到为每次此类时间维护的列表中:

def ids(iv,tm):
  ret=[[] for _ in tm]
  for nm,l,h in iv:
    for i in range(bisect.bisect_left(tm,l),bisect.bisect_right(tm,h)):
      ret[i].append(nm)
  return ret

当然,您可以使用dictziptm、idsiv、tm根据结果构建一个字典。

您可以提供一些具有所需输出的示例数据吗?它将类似于{1/1/2017上午9点可能是unix时间戳:[元组列表,其中tuple.start\u time好的。我建议你在你的帖子中添加一些数据,人们可以复制/粘贴。我知道这听起来很琐碎,但这是一种鼓励更多人回答的事情。当然,我编辑了一些数据,希望这会有帮助!只是为了确保:你没有太多的时间或太多的长时间重叠的intervals表示生成的一次性字典会占用太多内存,对吗?嘿,谢谢你提供的信息。我在发布问题后很快就切换到了迭代时间,所以交换了迭代顺序,你的二进制搜索点得到了进一步的改进。这似乎很好,所以谢谢增益!对于将来可能阅读的任何人来说,需要注意的一点是检查二分法_left=-1,因为这可能会产生意外的结果,具体取决于您的使用情况啊,我的错误,这是我代码中的一个错误!应该已经意识到-是,澄清一下,它不会返回-1
def ids(iv,tm):
  ret=[[] for _ in tm]
  for nm,l,h in iv:
    for i in range(bisect.bisect_left(tm,l),bisect.bisect_right(tm,h)):
      ret[i].append(nm)
  return ret