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).
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).
You can do it with one line, where you sum the range of numbers from 0 to n (the end is exclusive):
def problem1_3(n):
return sum(range(n+1))
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
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
Divide the elements of each column by their column-summations -
a/a.sum(axis=0,keepdims=1) # or simply : a/a.sum(0)
For making the row-summations unity, change the axis input -
a/a.sum(axis=1,keepdims=1)
Sample run -
In [78]: a = np.random.rand(4,5)
In [79]: a
Out[79]:
array([[ 0.37, 0.74, 0.36, 0.41, 0.44],
[ 0.51, 0.86, 0.91, 0.03, 0.76],
[ 0.56, 0.46, 0.01, 0.86, 0.38],
[ 0.72, 0.66, 0.56, 0.84, 0.69]])
In [80]: b = a/a.sum(axis=0,keepdims=1)
In [81]: b.sum(0) # Verify
Out[81]: array([ 1., 1., 1., 1., 1.])
To make sure it works on int arrays as well for Python 2.x, use from __future__ import division or use np.true_divide.
For columns adding upto 0
For columns that add upto 0, assuming that we are okay with keeping them as they are, we can set the summations to 1, rather than divide by 0, like so -
sums = a.sum(axis=0,keepdims=1);
sums[sums==0] = 1
out = a/sums
for i in range(len(A[0])):
col_sum = A[:, i].sum()
if col_sum != 0:
A[:, i] = A[:, i]/col_sum
else:
pass
The for loop is a bit sloppy and I'm sure there's a much more elegant way but it works.
Replace pass with A[:, i] = 1/len(A[0]) to eliminate dangling nodes and make the matrix column stocastic.
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.
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) )
np.empty creates an array containing uninitialized data. In your code, you initialize an array output of length 24 but assign only 22 values to it. The last 2 values contain arbitrary values (i.e. garbage). Unless performance is of importance, np.zeros is usually the better choice for initializing arrays since all values will have a consistent value of 0.
You can solve this without a for loop by padding the input array with zeros, then computing a vectorized sum.
import numpy as np
load = np.array([10, 12, 9, 13, 17, 23, 25, 28, 26, 24, 22, 20, 18, 20, 22, 24, 26, 28, 23, 24, 21, 18, 16, 13])
tmp = np.pad(load, [0, 2])
output = load + tmp[1:-1] + tmp[2:]
print(output)
Output
[31 34 39 53 65 76 79 78 72 66 60 58 60 66 72 78 77 75 68 63 55 47 29 13]
If the array is not super long, and you don't care too much about memory utilization you could use:
from itertools import zip_longest
output = [sum([x, y, z]) for x, y, z in zip_longest(load, load[1:], load[2:], fillvalue=0)]
Output is:
[31, 34, 39, 53, 65, 76, 79, 78, 72, 66, 60, 58, 60, 66, 72, 78, 77, 75, 68, 63, 55, 47, 29, 13]