So there are some changes that can be made. As you are running a nested for loop that should be the first candidate for removal, python isn't the best with lots of loops. I've made some changes below to improve your code.
- Here we actually use
n, instead of
ind, they are the same, so
ind is excessive
- I've expanded the
if ... else block as this improves readability
- I've changed
x as this is easier to quickly differentiate from
new_arr = 
for n in range(len(_arr)):
v = 1
for m, x in enumerate(_arr):
if m != n:
v *= x
v *= 1
I have two methods that work, one is pure python (using two core libraries), but could include numpy; the other is all numpy. They both work on a similar principal, that is that all new values are the same product (the entire array) divided by the value at the same index in the original array. Therefore, you can just divide the product of the entire array by each value in the original array, as long as there are no zero values (thanks One Lyner!).
from functools import reduce
from operator import mul
arr = [1, 2, 3, 4, 5]
arr_prod = reduce(mul, _arr) # You could use np.prod(_arr) instead of reduce(...)
return [arr_prod / x for x in _arr]
The pure python function could be a single line, but then you might end up computing the product of the entire array on every iteration.
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
return np.ones(_arr.shape) * _arr.prod() / _arr
# Even more succinct, thanks Graipher
return _arr.prod() / _arr
This Numpy solution would be vectorised and would scale well, but may be slower on smaller arrays. It works by creating a new
np.array of all
1; multiplying it by the product, so all the values are the product; finally dividing the 'product array' by the original array, which is element-wise.