список произведений элементов

Прошу помощи у сообщества, задача простейшая, но решить никак не получается. Дано Список чисел, пусть будет [1, 2, 3, 4] необходимо получить список, в котором каждый элемент равен произведению всех остальных элементов списка: [24, 12, 8, 6] - в случае с примером. у меня получилось решить задачу для суммы:

a = [1, 2, 3, 4] 
print([sum(a) - i for i in a])

как мне сделать для того, что бы получить произведения?

def product(a):
    pr = 1
    for i in a:
        pr *= i
    return pr
ans = [int(product(a)/i) for i in a]
print(ans)

Ответы (2 шт):

Автор решения: Stanislav Volodarskiy

В вашем коде я вижу три недостатка:

  • много раз вычисляется product, что делает ваше решение квадратичным по сложности, а можно уложиться в линейное время;

  • int(... / ...) теряет точность, переводя целые (которые в Питоне не ограничены) в вещественные (у которых 53 бита точности). Вот пример:

[9007199254740993, 9007199254740991] -> [9007199254740991, 9007199254740992]
  • неправильно обрабатываются нули в списке.

Возможное решение всех этих проблем ниже.

Код из вопроса int(... / ...) позволяет предположить что в списке только целые.

Наивное решение которое использует свежий Питон (3.8 и выше):

def naive_partial_products(a):
    # если Питон не свежий, то вычислите произведение так
    # p = functools.reduce(operator.mul, a, 1)
    p = math.prod(a)
    return [p // v for v in a]

Это короткое быстрое решение, которое хорошо работает пока в массиве нет нулей. Если нули есть, надо разбирать случаи. Если ноль один, то в ответе все нули кроме одного элемента. Если нулей больше одного, то в ответе одни нули.

Кроме нулей надо внимательно проследить как обрабатываются короткие массивы.

После учёта все возможностей получается такой симпатичный монстрик:

import math


def partial_products(a):
    zc = a.count(0)
    if zc > 1:
        return [0] * len(a)
    p = math.prod(v for v in a if v != 0)
    if zc == 0:
        return [p // v for v in a]
    return [p if v == 0 else 0 for v in a]


def check(a):
    print(f'{a} -> {partial_products(a)}')


check([])
check([0])
check([0, 0])
check([0, 0, 0])
check([10])
check([0, 10])
check([1, 2, 3, 4])
check([0, 1, 2, 3, 4])
check([0, 0, 1, 2, 3, 4])
$ python partial-products.py 
[] -> []
[0] -> [1]
[0, 0] -> [0, 0]
[0, 0, 0] -> [0, 0, 0]
[10] -> [1]
[0, 10] -> [10, 0]
[1, 2, 3, 4] -> [24, 12, 8, 6]
[0, 1, 2, 3, 4] -> [24, 0, 0, 0, 0]
[0, 0, 1, 2, 3, 4] -> [0, 0, 0, 0, 0, 0]
→ Ссылка
Автор решения: Vladimir Gonchar
import math

print([math.prod(a[:i] + a[i + 1:]) for i in range(len(a))])

так есть гуд?

import math
a = [0, 0, 1, 2, 3, 4]

temp_p = math.prod(a)
temp_i = a.count(0)
if temp_p == 0 and temp_i == 1:
    i = a.index(0)
    print([0] * i + [math.prod(a[:i] + a[i + 1:])] + [0] * (len(a) - i - 1))
elif temp_i > 1:
    print([0] * len(a))
else:
    print([temp_p // i for i in a])
→ Ссылка