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

2024-05-12 19:32:43 发布

您现在位置: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.product即可获得有序对的列表

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

然而,如果我对一个更大的列表执行此操作,我将得到一个内存错误,因此此解决方案对于可能有许多不同的有序对集的更大列表是不可伸缩的

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


Tags: of方法内存import列表错误情况product
1条回答
网友
1楼 · 发布于 2024-05-12 19:32:43

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)]

相关问题 更多 >