如何在Python中对列表的列表进行选择性笛卡尔积



我正在尝试从现有的列表中获得代表所有可能的有序对的列表列表。

import itertools
list_of_lists=[[0, 1, 2, 3, 4], [5], [6, 7],[8, 9],[10, 11],[12, 13],[14, 15],[16, 17],[18, 19],[20, 21],[22, 23],[24, 25],[26, 27],[28, 29],[30, 31],[32, 33],[34, 35],[36, 37],[38],[39]]

理想情况下,我们只使用itertools。

scenarios_list=list(itertools.product(*list_of_lists))

然而,如果我对一个更大的列表列表这样做,我就会得到一个内存错误,所以这个解决方案不适用于可能有许多不同的有序对集合的更大的列表列表。

那么,是否有一种方法可以建立一个过程,在这些有序对产生时,我们可以迭代它们,在将列表添加到另一个列表之前,我们可以测试列表是否满足一定的标准(例如测试是否有一定数量的偶数,列表的总和不能等于最大值,等等)。如果条件不满足,则不会添加有序对,因此当我们只关心某些有序对时,不会不必要地占用内存。

product的递归基实现开始:

def product(*lsts):
if not lsts:
yield ()
return
first_lst, *rest = lsts
for element in first_lst:
for rec_p in product(*rest):
p = (element,) + rec_p
yield p
[*product([1, 2], [3, 4, 5])]
# [(1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5)]

现在,你可以增加一个条件来过滤任何不满足它的p:

def product(*lsts, condition=None):
if condition is None:
condition = lambda tpl: True
if not lsts:
yield ()
return
first_lst, *rest = lsts
for element in first_lst:
for rec_p in product(*rest, condition=condition):
p = (element,) + rec_p
if condition(p):  # stop overproduction right where it happens
yield p

现在你可以-例如-只限制偶数元素:

[*product([1, 2], [3, 4, 5], condition=lambda tpl: not any(x%2 for x in tpl))]
# [(2, 4)]

相关内容

  • 没有找到相关文章

最新更新