在扩展列表上迭代

aiqt4smr  于 2021-08-25  发布在  Java
关注(0)|答案(2)|浏览(297)

假设我有一个列表:

lst = [0, 1, 2, 3, 4, 5, 6...]

我想以扩展的方式迭代这个列表,这样循环中的每次迭代都会得到:
1次迭代: [0] 2迭代: [0, 1] 3迭代: [0, 1, 2] 4迭代: [0, 1, 2, 3] ...
这基本上是为了模拟实时增长的时间序列。
我将lst的这一部分传递给另一个函数进行一些计算。
现在我这样做:

for i in range(1, len(lst)):
  my_func(lst[:i], other_variables)

男孩,这太慢了。我的列表包含超过100万个元素。我知道切片是列表的一个浅拷贝,也许我可以以某种方式避免拷贝,或者使用某种不同的方法。
我也试过:

lst2 = []

for i in range(len(lst)):
  lst2.append(lst[i])
  my_func(lst2, other_variables)

稍微好一点,但还是很慢。
我还尝试了deque()而不是list。

z0qdvdin

z0qdvdin1#

作为 i 越来越大, lst[:i] 越来越贵了。但您不需要在每次迭代中创建新的切片;只需附加 lst 指向预先存在的前缀。

pfx = []
for c in lst:
    pfx.append(c)
    my_func(pfx, other_variables)

你可以用 itertools.accumualte ,除了python没有一个很好的表达式用于向列表追加值并返回更新的列表之外。 pfx + [c] 也一样慢 lst[:i] .

qv7cva1a

qv7cva1a2#

在这个答案中提到的基础上,我们可以尝试避免点来提高性能。

lst2 = []
append = lst2.append
for c in lst:
    append(c)
    my_func(lst2, other_variables)

我们可以通过模拟测试看到性能的提高 my_func :

def my_func(kt):
    pass

def method1():
    lst2 = []
    for c in lst:
        lst2.append(c)
        my_func(lst2)

def method2():
    lst2 = []
    append = lst2.append
    for c in lst:
        append(c)
        my_func(lst2)
In [11]: %timeit method1()
84.8 ms ± 4.73 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [12]: %timeit method2()
67 ms ± 262 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

相关问题