How to Calculate Product of Array Except Self — From Basic to Blazing Fast
As a software engineer specializing in Python performance and data structure optimization, I've spent years turning slow, clunky algorithms into sleek, production-ready code.
One common problem many developers face is how to compute the "product of array except self," where you calculate the product of all other elements for each element in a list.
This article walks you through different implementations, starting with the most basic (but slow) and ending with an optimized, interview-ready solution.
If you're learning data structures and algorithms in Python or prepping for a coding interview, this breakdown is for you.
Brute Force: The Slow Start
from typing import List
def product(nums):
product = 1
j = 0
while j < len(nums):
product *= nums[j]
j += 1
return product
def product_of_array(nums: List[int]) -> List[int]:
nums2 = nums[:]
for i in range(len(nums)):
first = nums[:i] # All elements before i
second = nums[i+1:] # All elements after i
prod_val = product(first) * product(second)
nums2[i] = prod_val # Replace with product of others
return nums2
Why it's bad
For each element, it recomputes the product of all other elements.
Time Complexity: O(n^2) — terrible for significant inputs.
Think of this as using a toy car to run a delivery service. It works, but very slowly.
Here's similar code implemented differently,
from copy import deepcopy
def product(nums):
product=1
j=0
while j < len(nums):
product *=nums[j]
j +=1
return product
def product_of_array(nums):
nums2=deepcopy(nums)
nums3=deepcopy(nums)
for i in range(len(nums)):
nums3.pop(i)
prod_val=product(nums3)
nums2[i]=prod_val
nums3=deepcopy(nums)
return nums2
More brilliant Solution: Prefix and Suffix Products
We don't need to multiply everything again and again. We can instead calculate the prefix (product of everything to the left) and suffix (product of everything to the right) once.
from typing import List
def product_of_array(nums: List[int]) -> List[int]:
"""
Calculates the product of all elements except self for each index in the array.
Time Complexity: O(n), Space Complexity: O(n)
"""
n = len(nums)
result = [1] * n
prefix_product = 1
for i in range(n):
result[i] = prefix_product
prefix_product *= nums[i]
suffix_product = 1
for i in range(n - 1, -1, -1):
result[i] *= suffix_product
suffix_product *= nums[i]
return result
Why it's better
- Computes all prefix products in one pass.
- Then computes all suffix products in another pass.
- No need to slice arrays or recompute.
Time Complexity: O(n)
Space Complexity: O(n), but we only use constant extra variables for prefix/suffix.
It is like swapping your toy car for a motorbike. Much faster, much smarter.
Final Output Samples
print(f"Expected [24,12,8,6]: Actual:", product_of_array([1,2,3,4]))
print(f"Expected [0,0,0]: Actual:", product_of_array([0,4,0]))
print(f"Expected [1]*10**6: Actual:", product_of_array([1]*10**6))
print(f"Expected : Actual:", product_of_array([10**9]*10**5 ))
These cases confirm that the optimized solution efficiently handles edge cases and large data.
Your Code Deserves Better Tools
If you're still using brute-force methods for problems like "product of array except self," it's time to upgrade your toolbox.
The optimized version improves performance and is easier to maintain and reason about.
Next steps
Bookmark this pattern for coding interviews
Try modifying it to handle division and zero cases explicitly
Practice similar patterns with prefix sums, max/min arrays, etc.
Share this article with your team or coding group if you found it helpful.
Want more deep dives like this? Stay tuned to Python Haven.