如何从一组列表中获得笛卡尔积(每个可能的值组合)?
输入:
somelists = [
[1, 2, 3],
['a', 'b'],
[4, 5]
]
期望输出:
[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), (2, 'a', 5) ...]
请注意,"每个可能的组合"与"笛卡尔积"并不完全相同,因为在笛卡尔积中,允许重复。
是否有笛卡尔积的非重复版本?
@KJW是的,set(cartesian product)。
笛卡尔积中不应该有重复项,除非输入列表本身包含重复项。如果不希望笛卡尔积中有重复项,请在所有输入列表中使用set(inputlist)。不在结果上。
相关:大熊猫中的笛卡尔积,numpy中的笛卡尔积
在Python 2.6)
import itertools
for element in itertools.product(*somelists):
print(element)
文档:itertools.product Python 3
如果使用OP提供的变量someList,则只需添加"*"字符。
知道itertools.product()代码的效率吗?我认为它已经被优化了,但只是好奇(我不知道如何从docs页面计算它…)
@jaska:product()在结果中生成nitems_in_a_list ** nlists元素(reduce(mul, map(len, somelists)))。没有理由相信生成单个元素不是O(nlists)(摊销),即时间复杂度与简单嵌套for循环相同,例如,对于问题中的输入:nlists=3,结果中的元素总数:3*2*2,每个元素都有nlists项(在这种情况下,3。)
在某些列表之前,*的用法是什么?它是做什么的?
@vinetkumardoshi:这里,它用于将一个列表解压成函数调用的多个参数。阅读更多信息:stackoverflow.com/questions/36901/…
注意:只有当每个列表至少包含一个项时,此操作才有效
只是一个细节,但请注意,itertools.product()还可以处理生成器,而不只是列出类似的对象。
import itertools
>>> for i in itertools.product([1,2,3],['a','b'],[4,5]):
... print i
...
(1, 'a', 4