There is no need for a loop at all. You can use the triangular number formula:

n = int(input())
print(n * (n + 1) // 2)

A note about the division (//) (in Python 3): As you might know, there are two types of division operators in Python. In short, / will give a float result and // will give an int. In this case, we could use both operators, the only difference will be the returned type, but not the value. Since multiplying an odd with an even always gives an even number, dividing that by 2 will always be a whole number. In other words - n*(n+1) // 2 == n*(n+1) / 2 (but one would be x and the other x.0, respectively).

Answer from Akshat Tamrakar on Stack Overflow
🌐
NumPy
numpy.org › doc › stable › reference › generated › numpy.sum.html
numpy.sum — NumPy v2.5 Manual
An array with the same shape as a, with the specified axis removed. If a is a 0-d array, or if axis is None, a scalar is returned. If an output array is specified, a reference to out is returned. ... Equivalent method. ... Cumulative sum of array elements.
🌐
NumPy
numpy.org › doc › 2.0 › reference › generated › numpy.sum.html
numpy.sum — NumPy v2.0 Manual
Axis or axes along which a sum is performed. The default, axis=None, will sum all of the elements of the input array. If axis is negative it counts from the last to the first axis. New in version 1.7.0.
🌐
NumPy
numpy.org › doc › 2.1 › reference › generated › numpy.ndarray.sum.html
numpy.ndarray.sum — NumPy v2.1 Manual
Return the sum of the array elements over the given axis. Refer to numpy.sum for full documentation.
Top answer
1 of 3
9

You can make use of np.cumsum, and take the difference of the cumsumed array and a shifted version of it:

n = 3
arr = np.array([2, 4, 3, 7, 6, 1, 9, 4, 6, 5])
sum_arr = arr.cumsum()
shifted_sum_arr = np.concatenate([[np.NaN]*(n-1), [0],  sum_arr[:-n]])
sum_arr
=> array([ 2,  6,  9, 16, 22, 23, 32, 36, 42, 47])
shifted_sum_arr
=> array([ nan,  nan,   0.,   2.,   6.,   9.,  16.,  22.,  23.,  32.])
sum_arr - shifted_sum_arr
=> array([ nan,  nan,   9.,  14.,  16.,  14.,  16.,  14.,  19.,  15.])

IMO, this is a more numpyish way to do this, mainly because it avoids the loop.


Timings

def cumsum_app(flat_array, n):
    sum_arr = flat_array.cumsum()
    shifted_sum_arr = np.concatenate([[np.NaN]*(n-1), [0],  sum_arr[:-n]])
    return sum_arr - shifted_sum_arr

flat_array = np.random.randint(0,9,(100000))
%timeit cumsum_app(flat_array,10)
1000 loops, best of 3: 985 us per loop
%timeit cumsum_app(flat_array,100)
1000 loops, best of 3: 963 us per loop
2 of 3
7

You are basically performing 1D convolution there, so you can use np.convolve, like so -

# Get the valid sliding summations with 1D convolution
vals = np.convolve(flat_array,np.ones(n),mode='valid')

# Pad with NaNs at the start if needed  
out = np.pad(vals,(n-1,0),'constant',constant_values=(np.nan))

Sample run -

In [110]: flat_array
Out[110]: array([2, 4, 3, 7, 6, 1, 9, 4, 6, 5])

In [111]: n = 3

In [112]: vals = np.convolve(flat_array,np.ones(n),mode='valid')
     ...: out = np.pad(vals,(n-1,0),'constant',constant_values=(np.nan))
     ...: 

In [113]: vals
Out[113]: array([  9.,  14.,  16.,  14.,  16.,  14.,  19.,  15.])

In [114]: out
Out[114]: array([ nan,  nan,   9.,  14.,  16.,  14.,  16.,  14.,  19.,  15.])

For 1D convolution, one can also use Scipy's implementation. The runtimes with Scipy version seemed better for a large window size, as also the runtime tests listed next would try to investigate. The Scipy version for getting vals would be -

from scipy import signal
vals = signal.convolve(flat_array,np.ones(n),mode='valid')

The NaNs padding operation could be replaced by np.hstack : np.hstack(([np.nan]*(n-1),vals)) for better performance.


Runtime tests -

In [238]: def original_app(flat_array,n):
     ...:     sums = np.full(flat_array.shape, np.NaN)
     ...:     for i in range(n - 1, flat_array.shape[0]):
     ...:         sums[i] = np.sum(flat_array[i - n + 1:i + 1])
     ...:     return sums
     ...: 
     ...: def vectorized_app1(flat_array,n):
     ...:     vals = np.convolve(flat_array,np.ones(n),mode='valid')
     ...:     return np.hstack(([np.nan]*(n-1),vals))
     ...: 
     ...: def vectorized_app2(flat_array,n):
     ...:     vals = signal.convolve(flat_array,np.ones(3),mode='valid')
     ...:     return np.hstack(([np.nan]*(n-1),vals))
     ...: 

In [239]: flat_array = np.random.randint(0,9,(100000))

In [240]: %timeit original_app(flat_array,10)
1 loops, best of 3: 833 ms per loop

In [241]: %timeit vectorized_app1(flat_array,10)
1000 loops, best of 3: 1.96 ms per loop

In [242]: %timeit vectorized_app2(flat_array,10)
100 loops, best of 3: 13.1 ms per loop

In [243]: %timeit original_app(flat_array,100)
1 loops, best of 3: 836 ms per loop

In [244]: %timeit vectorized_app1(flat_array,100)
100 loops, best of 3: 16.5 ms per loop

In [245]: %timeit vectorized_app2(flat_array,100)
100 loops, best of 3: 13.1 ms per loop
🌐
W3Schools
w3schools.com › python › numpy › numpy_ufunc_summations.asp
NumPy ufuncs - Summations
Addition is done between two arguments whereas summation happens over n elements. ... import numpy as np arr1 = np.array([1, 2, 3]) arr2 = np.array([1, 2, 3]) newarr = np.add(arr1, arr2) print(newarr) Try it Yourself »
🌐
NumPy
numpy.org › doc › 2.1 › reference › generated › numpy.sum.html
numpy.sum — NumPy v2.1 Manual
Axis or axes along which a sum is performed. The default, axis=None, will sum all of the elements of the input array. If axis is negative it counts from the last to the first axis. New in version 1.7.0.
Find elsewhere
🌐
DigitalOcean
digitalocean.com › community › tutorials › numpy-sum-in-python
numpy.sum() in Python | DigitalOcean
From GPU-powered inference and Kubernetes to managed databases and storage, get everything you need to build, scale, and deploy intelligent applications.
🌐
GeeksforGeeks
geeksforgeeks.org › numpy-sum-in-python
numpy.sum() in Python - GeeksforGeeks
August 28, 2024 - Otherwise, it will consider arr to be flattened(works on all the axes). axis = 0 means along the column and axis = 1 means working along the row. out: Different array in which we want to place the result. The array must have the same dimensions as the expected output. The default is None. initial : [scalar, optional] Starting value of the sum. Return: Sum of the array elements (a scalar value if axis is none) or array with sum values along the specified axis. ... This Python program uses numpy.sum() to calculate the sum of a 1D array.
🌐
NumPy
numpy.org › doc › 2.3 › reference › generated › numpy.sum.html
numpy.sum — NumPy v2.3 Manual
An array with the same shape as a, with the specified axis removed. If a is a 0-d array, or if axis is None, a scalar is returned. If an output array is specified, a reference to out is returned. ... Equivalent method. ... Cumulative sum of array elements.
🌐
NumPy
numpy.org › doc › 1.22 › › reference › generated › numpy.sum.html
numpy.sum — NumPy v1.22 Manual
Axis or axes along which a sum is performed. The default, axis=None, will sum all of the elements of the input array. If axis is negative it counts from the last to the first axis. New in version 1.7.0.
🌐
Sharp Sight
sharpsight.ai › blog › numpy-sum
How to Use the Numpy Sum Function - Sharp Sight
February 6, 2024 - Now that we have our 1-dimensional array, let’s sum up the values. Doing this is very simple. We’re going to call the NumPy sum function with the code np.sum().
🌐
NumPy
numpy.org › devdocs › reference › generated › numpy.sum.html
numpy.sum — NumPy v2.6.dev0 Manual
An array with the same shape as a, with the specified axis removed. If a is a 0-d array, or if axis is None, a scalar is returned. If an output array is specified, a reference to out is returned. ... Equivalent method. ... Cumulative sum of array elements.
Top answer
1 of 5
9

That's literally just a dot product:

result = numpy.dot(list1, list2)

Note that if you're using NumPy, you shouldn't be using lists to represent your matrices and vectors. NumPy arrays are much more efficient and convenient for that.

2 of 5
5

for build-in you can use zip to group together elements in the same index position

list1 = [2,3,4]
list2 = [3,3,3]
result = sum( x*y for x,y in zip(list1, list2) )

About the edit

A buil-in version would be

from math import log
result = sum( log(i)*y for i,y in enumerate(list1,1) )

a more generalized version would be

import operator
def dotproduct(vec1, vec2, sum=sum, map=map, mul=operator.mul):
    return sum(map(mul, vec1, vec2))    

where you can provide whatever function you like for any of its part, then the first one is

result = dotproduct(list1,list2)

and the second is could be

result = dotproduct(range(1,len(list1)+1),list1, mul=lambda i,x:log(i)*x )
#                        ^ the i                    ^ how to operate

or

result = dotproduct(map(log,range(1,len(list1)+1) ), list1 )
#                           ^ the log i

the point being that you calculate the second vector accordingly

with numpy is more easy

import numpy as np
logi = np.log(np.arange(1,len(list1)+1)
result = np.dot(logi,list1)

which again boils down to calculate the parts accordingly


you can also make such that instead of receiving 2 vectors/lists it only work with one and receive a function that work in the element and its index

def sum_serie(vect, fun = lambda i,x:x, i_star=0): #with that fun, is like the regular sum
    return sum( fun(i,x) for i,x in enumerate(vect, i_star) )

and use it as

result = sum_serie( list1, lambda i,x:log(i)*x, 1)

from the comments, if I get it right, then something like this

from itertools import islice
def sum_serie(vect, *slice_arg, fun = lambda x:x): #with that fun, is like the regular sum
    """sum_serie(vect, [start,]stop[,step], fun = lambda x:x)"""
    if not slice_arg:
        slice_arg = (0,None,None)
    return sum( fun(x) for x in islice(vect, *slice_arg) )

or with enumerate as before

from itertools import islice
def sum_serie_i(vect, *slice_arg, fun = lambda i,x:x): #with that fun, is like the regular sum
    if not slice_arg:
        slice_arg = (0,None,None)
    return sum( fun(i,x) for i,x in islice(enumerate(vect), *slice_arg) )

and use, for example as

sum_serie( x, 0, 100, 2, fun=lambda xi: c*xi) #for arbitrary constant c
sum_serie_i( x, 0, 100, 2, fun=lambda i,xi: log(i)*xi)

Note: this way it accept the serie/iterable/whatever and at most 3 positional argument with the same meaning as those from range

Note 2: that is for PY3 which make fun a key-word only argument, in python 2 the same effect is accomplished with

def sum_serie_i(vect, *slice_arg, **kargv): 
    fun = kargv.get('fun', lambda i,x:x) #with that fun, is like the regular sum
    if not slice_arg:
        slice_arg = (0,None,None)
    return sum( fun(i,x) for i,x in islice(enumerate(vect), *slice_arg) )
🌐
SciPy
docs.scipy.org › doc › numpy-1.15.1 › reference › generated › numpy.sum.html
numpy.sum — NumPy v1.15 Manual
August 23, 2018 - Cumulative sum of array elements. ... Integration of array values using the composite trapezoidal rule. ... Arithmetic is modular when using integer types, and no error is raised on overflow.
🌐
DataCamp
datacamp.com › doc › numpy › sum
NumPy sum()
NumPy's `sum()` function is a powerful tool for array computation and analysis, allowing users to efficiently compute the sum of array elements along a specified axis.