returns 输出不同长度的笛卡尔积
Cartesian product that returns outputs of varied lengths
所以我有这些列表:
a = [1, 2, 3]
b = [11, 12, 13, 14]
c = [21, 22, 23, 24, 25, 26]
我想获取所有可能的组合(重复即可),其中包含 a
中的 2 个元素、b
中的 3 个元素和 c
中的 3 个元素。像这样:
([1, 2], [11, 12, 13], [21, 22, 23]) # 1
([1, 2], [11, 12, 13], [22, 23, 24]) # 2
# all the way to...
([2, 3], [12, 13, 14], [24, 25, 26]) # 16
如果我使用 itertools.product()
,它只会从每个列表中给我 1 个:
import itertools
def cartesian(the_list):
for i in itertools.product(*the_list):
yield i
a = [1, 2, 3]
b = [11, 12, 13, 14]
c = [21, 22, 23, 24, 25, 26]
test = cartesian([a, b, c])
print(next(test))
# Gives (1, 11, 21). But I need ([1, 2], [11, 12, 13], [21, 22, 23])
print(next(test))
# Gives (1, 11, 22). But I need ([1, 2], [11, 12, 13], [22, 23, 24])
我可以使用多个嵌套 for
循环,但如果我有很多列表,我将需要太多循环。
那么我该如何实现一个算法来给出所有可能的组合,每个组合由每个输入列表中一定数量的元素组成?
构建一个可以生成任意数量值的生成器函数,并在 product
中使用它,就像这样
>>> from itertools import product
>>> def get_chunks(items, number=3):
... for i in range(len(items) - number + 1):
... yield items[i: i + number]
...
...
然后定义你的 cartesian
生成器,像这样
>>> def cartesian(a, b, c):
... for items in product(get_chunks(a, 2), get_chunks(b), get_chunks(c)):
... yield items
...
...
如果你使用的是Python 3.3+,你其实可以在这里使用yield from
,像这样
>>> def cartesian(a, b, c):
... yield from product(get_chunks(a, 2), get_chunks(b), get_chunks(c))
...
然后,当你将所有元素作为一个列表获取时,你将得到
>>> from pprint import pprint
>>> pprint(list(cartesian([1, 2, 3],[11, 12, 13, 14],[21, 22, 23, 24, 25, 26])))
[([1, 2], [11, 12, 13], [21, 22, 23]),
([1, 2], [11, 12, 13], [22, 23, 24]),
([1, 2], [11, 12, 13], [23, 24, 25]),
([1, 2], [11, 12, 13], [24, 25, 26]),
([1, 2], [12, 13, 14], [21, 22, 23]),
([1, 2], [12, 13, 14], [22, 23, 24]),
([1, 2], [12, 13, 14], [23, 24, 25]),
([1, 2], [12, 13, 14], [24, 25, 26]),
([2, 3], [11, 12, 13], [21, 22, 23]),
([2, 3], [11, 12, 13], [22, 23, 24]),
([2, 3], [11, 12, 13], [23, 24, 25]),
([2, 3], [11, 12, 13], [24, 25, 26]),
([2, 3], [12, 13, 14], [21, 22, 23]),
([2, 3], [12, 13, 14], [22, 23, 24]),
([2, 3], [12, 13, 14], [23, 24, 25]),
([2, 3], [12, 13, 14], [24, 25, 26])]
所以我有这些列表:
a = [1, 2, 3]
b = [11, 12, 13, 14]
c = [21, 22, 23, 24, 25, 26]
我想获取所有可能的组合(重复即可),其中包含 a
中的 2 个元素、b
中的 3 个元素和 c
中的 3 个元素。像这样:
([1, 2], [11, 12, 13], [21, 22, 23]) # 1
([1, 2], [11, 12, 13], [22, 23, 24]) # 2
# all the way to...
([2, 3], [12, 13, 14], [24, 25, 26]) # 16
如果我使用 itertools.product()
,它只会从每个列表中给我 1 个:
import itertools
def cartesian(the_list):
for i in itertools.product(*the_list):
yield i
a = [1, 2, 3]
b = [11, 12, 13, 14]
c = [21, 22, 23, 24, 25, 26]
test = cartesian([a, b, c])
print(next(test))
# Gives (1, 11, 21). But I need ([1, 2], [11, 12, 13], [21, 22, 23])
print(next(test))
# Gives (1, 11, 22). But I need ([1, 2], [11, 12, 13], [22, 23, 24])
我可以使用多个嵌套 for
循环,但如果我有很多列表,我将需要太多循环。
那么我该如何实现一个算法来给出所有可能的组合,每个组合由每个输入列表中一定数量的元素组成?
构建一个可以生成任意数量值的生成器函数,并在 product
中使用它,就像这样
>>> from itertools import product
>>> def get_chunks(items, number=3):
... for i in range(len(items) - number + 1):
... yield items[i: i + number]
...
...
然后定义你的 cartesian
生成器,像这样
>>> def cartesian(a, b, c):
... for items in product(get_chunks(a, 2), get_chunks(b), get_chunks(c)):
... yield items
...
...
如果你使用的是Python 3.3+,你其实可以在这里使用yield from
,像这样
>>> def cartesian(a, b, c):
... yield from product(get_chunks(a, 2), get_chunks(b), get_chunks(c))
...
然后,当你将所有元素作为一个列表获取时,你将得到
>>> from pprint import pprint
>>> pprint(list(cartesian([1, 2, 3],[11, 12, 13, 14],[21, 22, 23, 24, 25, 26])))
[([1, 2], [11, 12, 13], [21, 22, 23]),
([1, 2], [11, 12, 13], [22, 23, 24]),
([1, 2], [11, 12, 13], [23, 24, 25]),
([1, 2], [11, 12, 13], [24, 25, 26]),
([1, 2], [12, 13, 14], [21, 22, 23]),
([1, 2], [12, 13, 14], [22, 23, 24]),
([1, 2], [12, 13, 14], [23, 24, 25]),
([1, 2], [12, 13, 14], [24, 25, 26]),
([2, 3], [11, 12, 13], [21, 22, 23]),
([2, 3], [11, 12, 13], [22, 23, 24]),
([2, 3], [11, 12, 13], [23, 24, 25]),
([2, 3], [11, 12, 13], [24, 25, 26]),
([2, 3], [12, 13, 14], [21, 22, 23]),
([2, 3], [12, 13, 14], [22, 23, 24]),
([2, 3], [12, 13, 14], [23, 24, 25]),
([2, 3], [12, 13, 14], [24, 25, 26])]