设置长度的可变变量,带有循环追加和切片

时间:2018-11-28 17:07:39

标签: python numpy deque

我有一个列表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数组。

2 个答案:

答案 0 :(得分:0)

我认为data_list = data_list[len(new_info):]很好。切片的访问权限为O(n)。

这就是问题,我认为这都不严格符合您的要求,因为在第2行和第3行之间存在一个(非常小的)间隔,其中列表lenlen(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)

一些想法:

  1. 如果起点是 deque()的子类,则您的代码list(itertools.islice(self, start, stop, step))可能是切片的最快方法。我能看到的唯一改进是,当最左边的切片索引位于中心线的右侧时,用reversed(self)添加一个特殊情况。

  2. 要支持定长要求,请使用deque的 maxlen 参数。

  3. 令人担忧的部分是要求,“每次我都要为计算创建一个新的numpy数组”。那是昂贵的部分。一般规则是,如果需要numpy,则数据应以numpy开始到结束。我只是让numpy数组增长到最大可容忍的大小,然后让numpy的快速,灵活的切片提供数据的必要视图,而无需复制并且无需在Python对象之间进行转换。