С математической точки зрения произведение без элементов должно давать нейтральный элемент операции произведение , что бы это ни было.
Например, для целых чисел нейтральный элемент умножения равен 1 , поскольку 1 ⋅ a = a для всех целых чисел a .Таким образом, пустое произведение целых чисел должно быть 1 .При реализации функции python, которая возвращает произведение списка чисел, это происходит естественным образом:
def iproduct(lst):
result = 1
for i in lst:
result *= i
return result
Для правильного вычисления результата с помощью этого алгоритма result
необходимо инициализировать с помощью 1
,Это приводит к возвращаемому значению 1
, когда функция вызывается в пустом списке.
Это возвращаемое значение также очень разумно для цели функции.С хорошей функцией продукта не должно иметь значения, если вы сначала объедините два списка, а затем создадите продукт из элементов, или если вы сначала создадите продукт из обоих отдельных списков, а затем умножите результаты:
iproduct(xs + ys) == iproduct(xs) * iproduct(ys)
Если xs
или ys
пусто, это работает, только если iproduct([]) == 1
.
Теперь более сложный product()
на итераторах.Здесь также, с математической точки зрения, product([])
должен возвращать нейтральный элемент этой операции, какой бы она ни была.Это не []
, поскольку product([], xs) == []
, в то время как для нейтральных элементов product([], xs) == xs
должно удерживаться.Оказывается, однако, что [()]
также не является нейтральным элементом:
>>> list(product([()], [1,2,3]))
[((), 1), ((), 2), ((), 3)]
На самом деле, product()
на самом деле не очень хороший математический продукт вообще, так как вышеприведенное уравнение не 't hold:
product(*(xs + ys)) != product(product(*xs), product(*ys))
Каждое применение продукта генерирует дополнительный слой кортежей, и нет никакого способа обойти это, поэтому даже не может быть реального нейтрального элемента.[()]
подходит довольно близко, хотя он не добавляет и не удаляет какие-либо элементы, он просто добавляет пустой кортеж к каждому.
[()]
фактически будет нейтральным элементом этой слегка адаптированной функции продукта, котораяработает только со списками кортежей, но не добавляет дополнительные слои кортежей для каждого приложения:
def tproduct(*xss):
# the parameters have to be lists of tuples
return (sum(rs, ()) for rs in product(*xss))
Для этой функции выполняется приведенное выше уравнение продукта:
def tup(x): return (x,)
txs = [map(tup, x) for x in xs]
tys = [map(tup, y) for y in ys]
tproduct(*(txs + tys)) == tproduct(tproduct(*txs), tproduct(*tys))
С дополнительной предварительной обработкойшаг упаковки списков ввода в кортежи, tproduct()
дает тот же результат, что и product()
, но ведет себя лучше с математической точки зрения.Также его нейтральным элементом является [()]
,
Так что [()]
имеет некоторый смысл в качестве нейтрального элемента этого вида умножения списка.Даже если он не совсем подходит product()
, это хороший выбор для этой функции, поскольку, например, он позволяет определять tproduct()
без необходимости вводить специальный случай для пустого ввода.