遍历 itertools.combinations 对象的生成器需要永远

Iterating through a generator of itertools.combinations object takes forever

编辑::
在评论中与 juanpa 和 fusion 以及 python chat 上的 Kevin 进行了所有这些讨论之后,我得出的结论是 iterating 通过 generator 所花费的时间与 iterating 通过任何其他对象,因为生成器本身会动态生成那些 combinations。此外,融合方法对 len(arr)1000(可能高达 5k - 但由于超时而终止,当然是在线判断 - 请注意它不是因为试图获得 min_variance_sub,但我还必须获得 min_variance_sub 中所有可能对的 sum of absolute differences)。我将接受融合的方法作为这个问题的答案,因为它回答了这个问题。 但我也会为该问题陈述创建一个新问题(更像是 QnA,我还将在其中回答 future visitors 的问题 - 我从其他候选人提交的内容中得到答案,editorial 问题 setter,以及问题 setter 自己的代码 - 虽然我不明白他们使用的方法)。我将 link 创建另一个问题 :)

下面开始原题

我在数组上使用 itertools.combinations 所以首先我尝试了

aList = [list(x) for x in list(cmb(arr, k))]

其中 cmb = itertools.combinations,arr 是列表,k 是一个整数。 这对 len(arr) < 20 左右非常有效,但是当 len(arr) 变为 50 或更多时,这 Raised a MemoryError

根据 kevin 在 Python Chat 上的建议,我使用了 generator,它在生成像这样的组合时速度惊人地快

aGen = (list(x) for x in cmb(arr, k))

但是遍历这个生成器对象太慢了。 我试过类似

for p in aGen:
    continue

甚至这段代码似乎也需要很长时间。

凯文还提出了一个关于 kth combination 的答案,这很好,但在我的情况下,我实际上想测试所有可能的组合和 select 与 minimum variance 的组合。

那么检查数组(列表)的所有可能组合是否具有 minimum variance 的内存有效方式是什么(准确地说,我只需要考虑恰好有 k 个元素的子数组)

感谢您的帮助。

您可以先对 n 个元素的列表进行排序,

然后使用 window 沿着排序后的列表移动 window 长度。

并找到 n-k+1 种可能组合的最小方差。

最小值应该是所有组合中的最小值。

 
def myvar(arr):
    l = len(arr)
    m = sum(arr)/l
    return sum((i-m)**2 for i in arr)/l


input_list = [.......]

sorted_list = sorted(input_list)

variance = None
min_variance_sub = None
for i in range(len(sorted_list) - k + 1):
    sub = sorted_list[i:i+k]
    var = myvar(sub)
    if variance is None or var<variance:
        variance = var
        min_variance_sub=sub
print(min_variance_sub)