Related to MrZizoScream's Product Array kata. You might want to solve that one first :)

```if:javascript
**Note:** Node 10 has now been enabled, and you can now use its BigInt capabilities if you wish, though your resulting array must still contain strings (e.g. "99999999999", not 9999999999n)

Pre-node 10: You will need to use the BigNumber.js library! Please use `.toFixed(0)` or `.toPrecision()` to round instead of `.toString(10)`, as the latter is _very_ slow
```

This is an adaptation of a problem I came across on LeetCode. 

Given an array of numbers, your task is to return a new array where each index (`new_array[i]`) is equal to the product of the original array, except for the number at that index (`array[i]`).

**Two things to keep in mind:**

* Zeroes will be making their way into some of the arrays you are given
* O(n^2) solutions will not pass.

Examples:

**Note**: All inputs will be valid arrays of nonzero length.

Have fun! Please upvote if you enjoyed :)

Source: codewars | Difficulty: EASY
Tags: Fundamentals

Data structures

Starter code: def product_sans_n(nums):
	

Solutions:
from functools import reduce

def product_sans_n(nums):
	z = nums.count(0)
	if z > 1:
		return [0] * len(nums)
	p = reduce(int.__mul__, (v for v in nums if v))
	return [not v and p for v in nums] if z else [p // v for v in nums]


from functools import reduce

def product_sans_n(nums):
	(z, p) = (nums.count(0), reduce(int.__mul__, (n for n in nums if n)))
	return [0 for _ in nums] if z > 1 else [0 if n else p for n in nums] if z else [p // n for n in nums]


from functools import reduce
from operator import mul

def mulsum(xs):
	return reduce(mul, xs, 1)

def product_sans_n(nums):
	nz = nums.count(0)
	if nz > 1:
		return [0] * len(nums)
	elif nz:
		return [0 if x else mulsum([_f for _f in nums if _f]) for x in nums]
	xs = mulsum(nums)
	return [xs // x for x in nums]


from functools import reduce

def product_sans_n(nums):
	if len([x for x in nums if x == 0]) > 1:
		return [0] * len(nums)
	from operator import mul
	from functools import reduce
	onezero = 0 in nums
	product = reduce(mul, nums if not onezero else nums[:nums.index(0)] + nums[nums.index(0) + 1:])
	if onezero:
		return list(map(lambda x: 0 if x != 0 else product, nums))
	else:
		return list(map(lambda x: product / x, nums))


def product_sans_n(l):
	contains_zeroes = False
	product = 1
	for n in l:
		if n:
			product *= n
		elif not contains_zeroes:
			contains_zeroes = True
		else:
			return [0] * len(l)
	return [0 if n else product for n in l] if contains_zeroes else [product // n for n in l]


def product_sans_n(nums):
	(zeros, product) = (0, 1)
	for n in nums:
		if n:
			product *= n
		else:
			zeros += 1
	return [zeros < 2 and (not n and product if zeros else product // n) for n in nums]


from operator import mul
from functools import reduce

def product_sans_n(nums):
	z = nums.count(0)
	p = 0 if z > 1 else reduce(mul, (x for x in nums if x != 0), 1)
	return [p // x if x != 0 and z == 0 else p if x == 0 and z == 1 else 0 for x in nums]


from functools import reduce

def product_sans_n(nums):
	s = set(nums)
	if 0 in s:
		return [reduce(int.__mul__, nums[:i] + nums[i + 1:]) for (i, e) in enumerate(nums)]
	else:
		prod = reduce(int.__mul__, nums)
		return [prod // n for n in nums]


from functools import reduce

def product_sans_n(nums):
	(zero, prod) = (nums.count(0), reduce(int.__mul__, (n for n in nums if n)))
	if zero:
		return [0 for _ in nums] if zero > 1 else [0 if n else prod for n in nums]
	return [prod // n for n in nums]


from itertools import accumulate, chain, islice
from operator import mul

def product_sans_n(nums):
	forward = islice(accumulate(chain([1], nums), mul), 0, len(nums), 1)
	backward = list(accumulate(chain([1], reversed(nums)), mul))[-2::-1]
	return list(map(mul, forward, backward))


from functools import reduce

def product_sans_n(nums):
	if nums.count(0) > 1:
		return [0 for i in nums]
	elif nums.count(0) == 1:
		prod = reduce(lambda a, b: a * b, [x for x in nums if x != 0])
		return [0 if i != 0 else prod for i in nums]
	else:
		prod = reduce(lambda a, b: a * b, nums)
		return [prod // i for i in nums]


import numpy as np

def product_sans_n(nums):
	numLen = len(nums)
	leftProducts = [None for _ in range(numLen)]
	rightProducts = [None for _ in range(numLen)]
	leftRunningProduct = 1
	rightRunningProduct = 1
	for i in range(numLen):
		leftRunningProduct = leftRunningProduct * nums[i]
		leftProducts[i] = leftRunningProduct
		rightRunningProduct = rightRunningProduct * nums[numLen - 1 - i]
		rightProducts[numLen - 1 - i] = rightRunningProduct
	result = [None for _ in range(numLen)]
	for i in range(numLen):
		product = 1
		if i > 0:
			product = product * leftProducts[i - 1]
		if i < numLen - 1:
			product = product * rightProducts[i + 1]
		result[i] = product
	return result


def product_sans_n(nums):
	p = 1
	zeroes = nums.count(0)
	for n in nums:
		if n:
			p *= n
	return [zeroes < 2 and (not n and p if zeroes else p // n) for n in nums]


from functools import reduce

def product_sans_n(nums):
	zeroes = nums.count(0)
	if zeroes >= 2:
		return [0 for x in nums]
	elif zeroes == 1:
		prod = reduce(int.__mul__, (x for x in nums if x != 0))
		return [0 if x != 0 else prod for x in nums]
	prod = reduce(int.__mul__, nums)
	return [prod // x for x in nums]


from functools import reduce
import operator

def product_sans_n(nums):
	prod = reduce(operator.mul, [x for x in nums if x != 0])
	zero_count = nums.count(0)
	for (index, value) in enumerate(nums):
		if value != 0 and zero_count != 0:
			nums[index] = 0
		elif value == 0 and zero_count > 1:
			nums[index] = 0
		elif value == 0:
			nums[index] = prod
		else:
			nums[index] = prod // value
	return nums


from functools import reduce

def product_sans_n(nums):
	if nums.count(0) > 1:
		return [0] * len(nums)
	if nums.count(0) == 1:
		i = nums.index(0)
		s = reduce(int.__mul__, nums[:i] + nums[i + 1:])
	t = reduce(int.__mul__, nums)
	return [s if x == 0 else t // x for x in nums]


import itertools
import operator

def product_sans_n(l):
	r = []
	p = list(itertools.accumulate(l, operator.mul))[-1]
	for i in range(len(l)):
		try:
			r.append(p // l[i])
		except:
			s = 1
			for j in range(len(l)):
				if i != j:
					s *= l[j]
			r.append(s)
	return r


from functools import reduce

def product(q):
	return reduce(int.__mul__, q)

def product_sans_n(q):
	if any((not x for x in q)):
		return [product(q[0:i] + q[i + 1:]) for (i, x) in enumerate(q)]
	else:
		n = product(q)
		return [n // x for x in q]


from numpy import prod

def product_sans_n(n):
	if n.count(0) > 1:
		return [0 for _ in n]
	p = 1
	for x in n:
		if x != 0:
			p *= x
	if n.count(0) == 1:
		return [0 if x != 0 else p for x in n]
	return [p // x for x in n]


from operator import mul
from functools import reduce

def product_sans_n(numbers):
	check = reduce(mul, numbers)
	out = []
	if not check:
		for i in range(len(numbers)):
			c = reduce(mul, numbers[:i] + numbers[i + 1:])
			out.append(c)
	else:
		for x in numbers:
			out.append(check // x)
	return out