How to reduce execution time in algorithm by replacing for loop in python

孤街浪徒 提交于 2019-12-02 05:17:57

You can try to use numpy.cumsum and get the average dividing by the index+1 of the cumsum list.

import numpy as np

l =  [100, 20, 50, 70, 45]

l_cumsum = np.cumsum(l)
l_indices = np.arange(1,len(l)+1,1)
l_average = np.divide(l_cumsum, l_indices).tolist()

print(l_average) # Outputs [100.0, 60.0, 56.666666666666664, 60.0, 57.0]

It should be pretty fast, O(n), since numpy.cumsum is very optimized already. If you still want it faster you could multithread it.

That is because you sum the whole array each time so the cost is quadratic, but can be linear if you reuse the previous result each time. Think about it.

Some ideas:

  1. Each time you run the av function, it reduces the whole list. Since calling av in your list comprehension, you're calling av more times than you need. You should be calculating your list of sums (using av) only once, and deriving your sums as you iterate through l.
  2. Since you are only summing up to i, you shouldn't be reducing the whole list. You should be slicing the first list l[:i], then running your reduce() against the shortened list.

As complete solutions have already spoiled the game, here is a working one in O(n).

Note that you can very often avoid manipulating indices yourself in Python. Here, we can use enumerate with a start value of 1 to keep track of the number of values we summed.

def means(lst):
    sum = 0
    out = []
    for n, new_val in enumerate(lst, 1): # we enumerate starting with n=1
        sum += new_val
        out.append(sum/n)
    return out

Some tests:

lst =  [100, 20, 50, 70, 45]
print(means(lst))
# [100.0, 60.0, 56.666666666666664, 60.0, 57.0]

print(means([]))
# []

What you want to do is iterate only once on the list:

i = [10,20,30,40,50,60,70]


def meanScores(l):
    if len(l) == 0: #Check is its an empty list
        return []
    res = [l[0]] #the first item is the first item in both lists(l)):
        res.append(float((res[i-1]*i + l[i])) / (i+1)) #Use the previous result to calculate the new result
    return [int(x) for x in res]

For using the previous results i take the previous sum (which is the prev avg * i), add the new number, and divide it by i+1.

It can be implemented with linear time complexity i.e O(n). A sample can be as follows just to give you an idea, how can you do it.

l =  [100, 20, 50, 70, 45]

a = [0] * len(l)

a[0] = l[0]

temp = a[0]

for i in range(1, len(l)):
    a[i] = (temp + l[i]) / (i + 1)
    temp = temp + l[i]

print(a)
Output
[100, 60.0, 56.666666666666664, 60.0, 57.0] 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!