提供一个空列表时,itertools.product()应该产生什么? [英] What should itertools.product() yield when supplied an empty list?

查看:90
本文介绍了提供一个空列表时,itertools.product()应该产生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想这是一个学术问题,但是第二个结果对我来说没有意义.它不应该像第一个一样空无一人吗?这种行为的依据是什么?

I guess it's an academic question, but the second result does not make sense to me. Shouldn't it be as thoroughly empty as the first? What is the rationale for this behavior?

from itertools import product

one_empty = [ [1,2], [] ]
all_empty = []

print [ t for t in product(*one_empty) ]  # []
print [ t for t in product(*all_empty) ]  # [()]

更新

感谢所有答案-非常有用.

Thanks for all of the answers -- very informative.

Wikipedia对空笛卡尔积的的讨论提供了明确的声明:

Wikipedia's discussion of the Nullary Cartesian Product provides a definitive statement:

无集的笛卡尔积... 是包含 空元组.

The Cartesian product of no sets ... is the singleton set containing the empty tuple.

这是一些代码,您可以用来通过有见地的

And here is some code you can use to work through the insightful answer from sth:

from itertools import product

def tproduct(*xss):
    return ( sum(rs, ()) for rs in product(*xss) )

def tup(x):
    return (x,)

xs = [ [1, 2],     [3, 4, 5]       ]
ys = [ ['a', 'b'], ['c', 'd', 'e'] ]

txs = [ map(tup, x) for x in xs ]  # [[(1,), (2,)], [(3,), (4,), (5,)]]
tys = [ map(tup, y) for y in ys ]  # [[('a',), ('b',)], [('c',), ('d',), ('e',)]]

a = [ p for p in tproduct( *(txs + tys) )                   ]
b = [ p for p in tproduct( tproduct(*txs), tproduct(*tys) ) ]

assert a == b

推荐答案

从数学的角度看,无论是什么元素,乘积都不会产生操作 product 的中性元素,无论是什么.

From a mathematical point of view the product over no elements should yield the neutral element of the operation product, whatever that is.

例如,在整数上,乘积的中性元素为 1 ,因为 1⋅所有整数 a 的a = a .因此,整数的空积应为 1 .实现返回返回数字列表的乘积的python函数时,自然会发生这种情况:

For example on integers the neutral element of multiplication is 1, since 1 ⋅ a = a for all integers a. So an empty product of integers should be 1. When implementing a python function that returns the product of a list of numbers, this happens naturally:

def iproduct(lst):
  result = 1
  for i in lst:
    result *= i
  return result

要使用此算法计算出正确的结果,需要使用1初始化result.在空列表上调用该函数时,这将导致返回值1.

For the correct result to be calculated with this algorithm, result needs to be initialized with 1. This leads to a return value of 1 when the function is called on an empty list.

此返回值对于该功能而言也是非常合理的.有了良好的乘积函数,先合并两个列表,然后构建元素的乘积,还是先构建两个列表的乘积,然后乘以结果,都没关系.

This return value is also very reasonable for the purpose of the function. With a good product function it shouldn't matter if you first concat two lists and then build the product of the elements, or if you first build the product of both individual lists and then multiply the results:

iproduct(xs + ys) == iproduct(xs) * iproduct(ys)

如果xsys为空,则仅在iproduct([]) == 1时有效.

If xs or ys is empty that only works if iproduct([]) == 1.

现在在迭代器上使用更复杂的product().同样,从数学的角度来看,product([])应该返回该操作的中性元素,无论是什么.它不是[],因为是product([], xs) == [],而中性元素product([], xs) == xs应该成立.但是事实证明,[()]也不是中立的元素:

Now the more complicated product() on iterators. Here also, from a mathematical point of view, product([]) should return the neutral element of that operation, whatever that is. It is not [] since product([], xs) == [], while for the neutral elements product([], xs) == xs should hold. It turns out, though, that [()] also isn't a neutral element:

>>> list(product([()], [1,2,3]))
[((), 1), ((), 2), ((), 3)]

实际上,product()根本不是一个非常好的数学乘积,因为上面的等式不成立:

In fact, product() is not really a very nice mathematical product at all, since this above equation doesn't hold:

product(*(xs + ys)) != product(product(*xs), product(*ys))

每个产品应用程序都会产生一个附加的元组层,并且没有办法解决这个问题,因此甚至不可能有一个真正的中性元素. [()]非常接近,它不添加或删除任何元素,它只是向每个元素添加一个空元组.

Each application of product generates an additional layer of tuples and there is no way around that, so there can't even be a real neutral element. [()] comes pretty close though, it doesn't add or remove any elements, it just adds an empty tuple to each.

[()]将是此功能稍有调整的乘积函数的中性元素,该函数仅对元组列表起作用,而不会在每个应用程序上添加其他元组层:

[()]would in fact be the neutral element of this slightly adapted product function that only operates on lists of tuples, but doesn't add additional tuple layers on each application:

def tproduct(*xss):
  # the parameters have to be lists of tuples
  return (sum(rs, ()) for rs in product(*xss))

对于此函数,以上乘积方程式成立:

For this function the above product equation holds:

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()相同,但是从数学角度来看,其表现更好.而且它的中性元素是[()]

With the additional preprocessing step of packing the input lists into tuples, tproduct() gives the same result as product(), but behaves nicer from a mathematical point of view. Also its neutral element is [()],

所以[()]在某种意义上是这种列表乘法的中立元素.即使它不完全适合product(),它也是此功能的不错选择,因为它例如允许定义tproduct(),而无需为空输入引入特殊情况.

So [()] makes some sense as the neutral element of this kind of list multiplication. Even if it doesn't exactly fit product() it is a good choice for this function since it for example allows to define tproduct() without the need to introduce a special case for empty input.

这篇关于提供一个空列表时,itertools.product()应该产生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆