加快循环,可能使用发电机?

时间:2017-08-02 01:29:07

标签: python performance iterator generator

我对python很新,我有一个问题,我在试图计算一个等式有多少解,例如Ta + Nb + Mc + Pd = e,其中输入e。我不关心解决方案是什么,只关心数量。

Abcd是可变正整数,NMPT是固定整数

我知道这是一个新手错误,但我尝试了4个嵌套for循环,它花了太长时间,所以我放弃了,但想不出更优雅的方式。即使我从允许循环中消除了潜在的数字,我仍然得到了更大的计算时间。

我已经读过关于生成器花费的时间少得多,但我不确定如何正确使用它们,我设法将时间缩短到一两分钟,但希望更快地使用带有yield的函数。

有点像,不完全是这样,但在这个程度上,是的,我知道嵌套循环是不利的,但我是一个新手,并试图学习。

def function():
    count = 0 
    for a is in range (0,e)
        for b is in range (0,int(e/N))
            Another for loop 
                Another for loop
                    count += 1
    yield count

输出它,它给了我更快的结果,但不够快。

或者我是以完全错误的方式思考这个问题?

由于

2 个答案:

答案 0 :(得分:1)

这是一类问题,其中更好的算法将比改变代码的工作方式产生更好的性能提升。

所以问题是,TNMPe会找到有多少解决方案。

现在像yield这样的东西适用于需要所有解决方案的情况......获取所有解决方案将涉及枚举所有解决方案,这将是4个嵌套循环... { {1}}可以为这种情况提供帮助。

计算解决方案使我们能够找到减少行走所需的技巧......

让我们从最外层的循环开始

yield

范围有多高?我们知道,要使解决方案有效,for a in range(1, ?) abc必须为正,即d所以我们可以如果>= 1,则a值最高...因此T*a + N*1 + M*1 + P*1 == e的上限为a

int((e - N - M - P) / T)

for a in range(1, int((e - N - M - P) / T)) for b in range(1, ?) 的范围有多高?我们知道我们已经b ......

T*a

for a in range(1, int((e - N - M - P) / T)) for b in range(1, int((e - T*a - M - P) / N)) for c in range(1, ?) 的范围有多高?同样的原则......

c

现在在这一点上你可能想要做另一个 for循环...但是这里我们需要聪明,如果我们可以避免最后一个循环...因为上限该范围实际上是有效解决方案的数量!

for a in range(1, int((e - N - M - P) / T))
  for b in range(1, int((e - T*a - M - P) / N))
    for c in range(1, int((e - T*a - N*b - P) / M))
      ?

这是一种优越的算法,因为它具有更少的循环,因此会更快地返回......

哦,但还有更多...如果你知道数学,如果我没记错,你当然可以删除另一个循环,如果不能删除所有这些...但这是你需要实际知道数学而不仅仅是强制解决方案

答案 1 :(得分:1)

加速嵌套for循环的常用方法是使用itertools.product()生成所有参数值,itertools.starmap()将参数应用于函数:

而不是:

for a in range(5):
    for b in range(8):
        for c in range(10, 17):
            for d in range(5, 11):
                 v = f(a, b, c, d)
                 ...

改为写下:

for v in starmap(f, product(range(5), range(8), range(10,17), range(5,11))):
    ...

好处是:

  • 更简洁的功能风格
  • 整数值只创建一次
  • 您不会不断重建相同的整数列表
  • product()只分配了一个元组并重新使用
  • starmap() product()都以C速度运行(没有纯粹的python步骤)
  • 功能" f"只查了一次。