【发布时间】:2021-12-05 19:50:44
【问题描述】:
我正在尝试从现有列表中获取代表所有可能有序对的列表。
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))
但是,如果我要为更大的列表列表执行此操作,我会遇到内存错误,因此对于可能存在大量不同组有序对的更大列表列表,此解决方案不可扩展。
那么,有没有一种方法可以设置一个流程,在这些有序对产生时我们可以迭代它们,在将列表附加到另一个列表之前,我们可以测试该列表是否满足特定标准(例如测试是否有一定数量的偶数,列表的总和不能等于最大值等)。如果不满足条件,则不会附加有序对,因此当我们只关心某些有序对时,不会不必要地占用内存。
【问题讨论】:
-
“在生成这些有序对时迭代它们”——这正是
itertools.product(*list_of_lists)让你做的事情。无需将所有组合存储在列表中。 -
itertools.product是一个生成器,而不仅仅是一个数组。所以你可以遍历它,它不会在第一次调用时创建整个数组 - 不需要所有内存 -
过滤
itertools.product的结果(不先将其转换为列表)是一种简单的方法。但是,如果它生成了这么多产品并且您最终会拒绝其中的很多产品,那么最好滚动您自己的递归生成器,该生成器会在产品被保证不符合标准时对其进行修剪。例如,如果您最多需要三个偶数并且您已经有部分 (0, 5, 6, 8),则 (10, 12, 14, 16 等) 中的任何一个都将被提前拒绝,从而为您节省大量时间。 -
@Reti43 您能否提供使用自定义生成器的示例答案?那会很有帮助。
-
您的选择标准是什么?
标签: python for-loop list-comprehension itertools cartesian-product