我有一个列表data_list
,应该一直保持一定的长度x
。
我每隔一定的时间间隔就会获得新的信息,然后执行以下操作
new_info # type: list
data_list.extend(new_info)
del data_list[:len(new_info)]
但是这非常慢(我认为del部分复制了整个列表)。
此外,在每次循环插入之后,我都会对列表进行切片,并使用numpy执行各种数值计算。 这意味着每次我都会为计算创建一个新的numpy数组。
您会推荐什么? 推荐的数据结构不在标准库中也没关系。
注意:
我一开始并没有所有的new_info
,所以不能分批完成。
我的尝试
import sys
import itertools
from typing import Iterable
from collections import deque
class SetLengthDeque(deque):
def __getitem__(self, s):
# for me the common case is a slice so i prefer this,
# rather then check the type of s each time
try:
start, stop, step = s.start or 0, s.stop or sys.maxsize, s.step or 1
return list(itertools.islice(self, start, stop, step))
except AttributeError: # not a slice but an int
return self[s]
但是deque
实际上是一个链表和一个循环数组。
插入时快约2个数量级,但切片时则比列表慢7倍。
再加上每次迭代我仍然必须创建一个numpy数组。
答案 0 :(得分:0)
我认为data_list = data_list[len(new_info):]
很好。切片的访问权限为O(n)。
这就是问题,我认为这都不严格符合您的要求,因为在第2行和第3行之间存在一个(非常小的)间隔,其中列表len
是len(data_list) + len(new_info)
。
data_list.extend(new_info) # Arbitrarily long
data_list[len(new_info):]
如果我们一次全部完成怎么办?
data_list = data_list.extend(new_info)[len(new_info):]
extend
没有返回值,所以我们得到一个错误。
编辑:这似乎可以解决,但我尚未对其进行彻底的测试
if len(new_info) < len(data_list):
data_list.extend(new_info)
data_list[len(new_info):]
else:
data_list = new_info[0-len(data_list):]
data_list
再次编辑:每个joshrogan我也用deque
尝试过
d = deque(data_list, maxlen=len(data_list))
j = deque([x for x in range(30)])
d.extend(j)
在您的用例中,我认为其中一个可能比另一个更有效,并且有兴趣了解它!
答案 1 :(得分:0)
一些想法:
如果起点是 deque()的子类,则您的代码list(itertools.islice(self, start, stop, step))
可能是切片的最快方法。我能看到的唯一改进是,当最左边的切片索引位于中心线的右侧时,用reversed(self)
添加一个特殊情况。
要支持定长要求,请使用deque的 maxlen 参数。
令人担忧的部分是要求,“每次我都要为计算创建一个新的numpy数组”。那是昂贵的部分。一般规则是,如果需要numpy,则数据应以numpy开始到结束。我只是让numpy数组增长到最大可容忍的大小,然后让numpy的快速,灵活的切片提供数据的必要视图,而无需复制并且无需在Python对象之间进行转换。