当前位置:  开发笔记 > 编程语言 > 正文

当提供空列表时,itertools.product()会产生什么?

如何解决《当提供空列表时,itertools.product()会产生什么?》经验,为你挑选了1个好方法。

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

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) ]  # [()]

更新

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

维基百科对Nullary Cartesian产品的讨论提供了一个明确的陈述:

没有集合的笛卡尔积......是包含空元组的单例集.

这里有一些代码可以用来处理来自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

sth.. 10

从数学的角度来看,无任何元素的产品应该产生操作产品的中性元素,无论是什么.

例如,对于整数,乘法的中性元素是1,因为对于所有整数a,1·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()根本不是一个非常好的数学产品,因为上面的等式不成立:

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()而不需要为空输入引入特殊情况.



1> sth..:

从数学的角度来看,无任何元素的产品应该产生操作产品的中性元素,无论是什么.

例如,对于整数,乘法的中性元素是1,因为对于所有整数a,1·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()根本不是一个非常好的数学产品,因为上面的等式不成立:

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()而不需要为空输入引入特殊情况.

推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有