Python 在itertools.combinations对象的生成器中迭代会花费很长时间
编辑::Python 在itertools.combinations对象的生成器中迭代会花费很长时间,python,list,generator,combinations,variance,Python,List,Generator,Combinations,Variance,编辑:: 在评论和Kevin on中与juanpa&fusion进行了所有这些讨论之后,我得出了一个结论,即通过生成器进行迭代所需的时间与通过任何其他对象进行迭代所需的时间相同,因为生成器本身会动态生成这些组合。此外,通过融合的方法对len(arr)到1000(可能高达5k-但它会因超时而终止,当然是在在线法官身上-请注意,这不是因为试图获得minu variance\u sub,而是我还必须获得minu variance\u sub中所有可能对的绝对差之和).我将接受fusion的方法作为这个
在评论和Kevin on中与juanpa&fusion进行了所有这些讨论之后,我得出了一个结论,即通过
生成器进行迭代
所需的时间与通过任何其他对象进行迭代
所需的时间相同,因为生成器本身会动态生成这些组合。此外,通过融合的方法对len(arr)
到1000
(可能高达5k
-但它会因超时而终止,当然是在在线法官身上-请注意,这不是因为试图获得minu variance\u sub
,而是我还必须获得minu variance\u sub
中所有可能对的绝对差之和
).我将接受fusion的方法作为这个问题的答案,因为它回答了这个问题。
但我也会为这个问题陈述提出一个新的问题(更像是一个QnA
,在这里我还将回答未来访客的问题
——我从其他候选人提交的材料中得到答案,一篇社论
,一篇问题解决者自己的代码——尽管我不理解他们使用的方法。我将在创建另一个问题时链接到另一个问题:)
是
原始问题从下面开始
我在数组上使用了itertools.compositions
,所以首先我尝试了以下方法
aList = [list(x) for x in list(cmb(arr, k))]
for p in aGen:
continue
其中,cmb=itertools.compositions
,arr为列表,k为整数。
这对len(arr)<20左右完全有效,但当len(arr)变为50或更多时,这会引起内存错误
根据kevin在Python Chat上的建议,我使用了一个生成器
,它以惊人的速度生成这样的组合
aGen = (list(x) for x in cmb(arr, k))
但是遍历这个生成器对象太慢了。
我试过类似的东西
aList = [list(x) for x in list(cmb(arr, k))]
for p in aGen:
continue
甚至这个代码似乎也要花很长时间
Kevin还提出了一个关于kth组合的答案,这很好,但在我的例子中,我实际上想测试所有可能的组合,并选择方差最小的组合
<> p> <强>那么,检查数组(列表)的所有可能组合的内存有效方式是:<代码>最小方差< /代码>(确切地说,我只需要考虑具有精确k元素的子数组)>/P>
谢谢您的帮助。您可以先使用n
元素对列表进行排序
然后使用一个k长度的移动窗口沿排序列表移动
并找出n-k+1
可能组合的最小方差
最小值应为所有组合的最小值
def myvar(arr):
l=长度(arr)
m=总和(arr)/l
返回金额((i-m)**2(对于arr中的i)/l
输入列表=[…]
已排序的列表=已排序(输入列表)
方差=无
最小方差=无
对于范围内的i(len(排序列表)-k+1):
sub=已排序的_列表[i:i+k]
var=myvar(子)
如果方差为None或var,则可以首先使用n
元素对列表进行排序
然后使用一个k长度的移动窗口沿排序列表移动
并找出n-k+1
可能组合的最小方差
最小值应为所有组合的最小值
def myvar(arr):
l=长度(arr)
m=总和(arr)/l
返回金额((i-m)**2(对于arr中的i)/l
输入列表=[…]
已排序的列表=已排序(输入列表)
方差=无
最小方差=无
对于范围内的i(len(排序列表)-k+1):
sub=已排序的_列表[i:i+k]
var=myvar(子)
如果方差为None或vark,那么这里的k是什么?几乎可以肯定,您只是在处理很多组合。注意,aGen=(cmb中x的列表(x)(arr,k))
不会生成组合,它会创建一个生成器,在您迭代时动态生成组合。因此,它当然非常快,在当前情况下,它实际上不起任何作用len(arr)是50,k是8。是的,组合的数量肯定很多。50选择8是536878650。5亿次迭代。假设你在每次迭代中所做的工作需要1毫秒,那么它将需要536878650*1e-3/(60*60)==149.13295833333333
需要几个小时才能完成。现在,您在每次迭代中所做的工作可能更少,但这让您很好地了解这可能需要多长时间。您对每个组合都在做什么操作?实际上,简单的方法可能更好,统计
包必须处理各种不同的numeric typs,它非常小心,因此有很多开销。我认为时间复杂度在任何情况下都不会有所不同,但当然,这里常数因子很重要这里什么是k?几乎可以肯定,您只是在处理很多组合。注意,aGen=(cmb中x的列表(x)(arr,k))
不会生成组合,它会创建一个生成器,在您迭代时动态生成组合。因此,它当然非常快,在当前情况下,它实际上不起任何作用len(arr)是50,k是8。是的,组合的数量肯定很多。50选择8是536878650。5亿次迭代。假设你在每次迭代中所做的工作需要1毫秒,那么它将需要536878650*1e-3/(60*60)==149.13295833333333
需要几个小时才能完成。现在,您在每次迭代中所做的工作可能更少,但这让您很好地了解这可能需要多长时间。您对每个组合都在做什么操作?实际上,简单的方法可能更好,统计
包必须处理各种不同的numeric typs,它非常小心,因此有很多开销。我认为时间复杂度在任何情况下都不会有所不同,但当然,这里的常数因子