Reputation: 87
I want to make a new list from the existing list such that each element in the new list is the product of all the numbers in the existing list except the element in the same position of a new list element.
For example [2,4,5] --> [20,10,8]
I came up with a solution wherein one for-loop, j traverses to the right side of the i-th (current) element while in other for loop, k covers the left side of the elements - Multiplies and gives the result.
def mulList():
oldList = [2,4,5]
newList = []
for i in range(len(oldList)):
a = 1
for j in range(i+1,len(oldList)):
a *= oldList[j]
for j in range(i-1,-1,-1):
a *= oldList[j]
newList.append(a)
print(newList)
mulList()
Later I got to know that we can solve it with two for-loops like this where I am not doing anything if i equals j
def mulList():
oldList = [2,4,5]
newList = []
for i in range(len(oldList)):
a = 1
for j in range(len(oldList)):
if j == i:
a += 0
else:
a *= oldList[j]
newList.append(a)
print(newList)
mulList()
I was wondering whether there is any better way to solve it with only one for loop.
Upvotes: 1
Views: 87
Reputation: 20490
You can take the product of all elements in the list via functools.reduce, and then divide each element in the list with the product using integer division //
from functools import reduce
from operator import mul
li = [2,4,5]
#Take product of all elements via reduce operation on the list
mult = reduce(mul, li)
#40
#Divide the product found in the step above by each item via integer division
res = [mult//item for item in li]
print(res)
You can also multiply elements in a for loop if you don't want to use functools.reduce
#Or loop over the element to multiply
mult = 1
for item in li:
mult *= item
The output will be
[20, 10, 8]
Upvotes: 2
Reputation: 1548
How about just this
c = 1
for i in oldList:
c *= i
newList = [c//e for e in oldList]
Now your function will be
def mulList():
oldList = [2,4,5]
c = 1
for i in oldList:
c *= i
newList = [c//e for e in oldList]
print(newList)
Upvotes: 0
Reputation: 21893
You can just multiply everything together once, and then loop through the elements again and divide the total product with the current element:
def mulList():
oldList = [2,4,5]
newList = []
total = 1
for x in oldList:
total *= x # total = total * x
for x in oldList:
# Use // to get int (4) instead of float (4.0)
newList.append(total // x)
print(newList)
Upvotes: 4
Reputation: 3419
I saw this question in leetcode I think and there was a constraint to not use division and still do this algorithm in O(n)
. Basically I traverse the array two times once in forward direction and once in reverse and the multipies corresponding elements in the third iteration to get the output you see.
oldlist = [2,4,5]
forwardlist=[1]*len(oldlist)
backwardlist=[1]*len(oldlist)
mul = oldlist[0]
for i in range(1,len(oldlist)):
forwardlist[i] = mul
mul*= oldlist[i]
mul = oldlist[len(oldlist) - 1]
for i in range(len(oldlist) - 2, -1, -1):
backwardlist[i] = mul
mul*= oldlist[i]
newlist = []
for i in range(len(oldlist)):
newlist.append(forwardlist[i]*backwardlist[i])
print(newlist)
OUTPUT
[20, 10, 8]
Hope that was helpful. :)
Upvotes: 1