Python在编译时卡住了

时间:2014-05-03 18:05:38

标签: python

我编写了一个程序,可以找到每个数字从1到20的最小数字作为倍数。我在C ++中的代码运行良好,并找到了正确的答案:

#include <iostream>

using namespace std;

int main(){

    for( int i = 1; i < 300000000; i++ ){

        int check = 1;

        for( int j = 6; j <= 20; j++ ){

            if( i % j == 0 ){

                continue;

            } else {

                check = 0;
                break;

            }

        }

        if( check == 1 ){

            cout << i << endl;
            break;

        }

    }

}

然而,Python中的相同程序 - 在找到最小数字时以1到10的倍数作为倍数,但只有当搜索的范围较小(它适用于5000000)时才起作用 - 根本不会编译。我继续下去,我必须关闭终端窗口。

for i in range( 1, 300000000 ):

    check = 1

    for j in range( 6, 21 ):
        if i % j == 0:
            continue
        else:
            check = 0
            break

    if check == 1:
        print i
        break

我正在使用Mac OS X Mavericks,如果这是相关的。

编辑:我尝试过切换到xrange,但遗憾的是没有区别。

Edit2:我把它留在了后台 - 事实上它只需要大约14分钟就可以运行!我道歉,我应该在第一时间做到这一点。

4 个答案:

答案 0 :(得分:2)

我猜你使用的是Python 2。

你的问题是:

range( 1, 300000000 )

您正在构建一个包含300000000个Python int对象的列表。如果我们假设Python中的int是4字节(非常 false),则分配300000000×4 = 1200000000字节= 1 GB。

您应该将其替换为以下内容:

xrange( 1, 300000000 )

xrange 的优点是它不会提前预先分配所有Python内联。有关详细信息,请参阅xrange的文档:

  

除了在内存饥饿的机器上使用非常大的范围外,xrange()超出范围()的优势是最小的[...]

使用Python 3时,此问题不再存在,因为 range 已被删除, xrange 已重命名为 range

请注意,这将解决您遇到的任何内存错误。这不能解决使用坏的慢速算法的问题。在处理数字时,Python并不是很快(但是当使用大数字时其他语言也会表现得很慢)。

答案 1 :(得分:1)

你是什么意思&#34;编译&#34;?你是如何编译Python代码的?

尝试使用xrange()

答案 2 :(得分:0)

如果这是python 2,那么你真的需要将range更改为xrangerange通过创建指定大小的列表来工作,然后逐项迭代。但是,在这种情况下,您不需要列表本身,只需要包含在该列表中的索引。所以你应该更喜欢xrange,因为它是一个生成器,这意味着它可以在不在内存中创建列表的情况下进行迭代。这将使您的程序不必创建一个非常大的列表,这将占用大量内存。

请注意,在Python 3中range具有与Python 2 xrange相同的行为。

for i in xrange( 1, 300000000 ):

    check = 1

    for j in xrange( 6, 21 ):
        if i % j == 0:
            continue
        else:
            check = 0
            break

    if check == 1:
        print i
        break

Python也是一种解释型语言,没有像c ++那样的编译步骤。你所看到的只是一个缓慢的运行时间。

答案 3 :(得分:0)

你的Python程序不是错误的,它只是非常慢,因为你使用的是非常糟糕的算法。

请改为尝试:

def gcd(a, b):
    while b:
        a, b = b, a%b
    return a

def lcm(a, b):
    return (a // gcd(a, b)) * b

res = 1
for i in range(2, 21):
    res = lcm(res, i)
print("Least common multiple of 1..20 is {}".format(res))

编辑:或者,您可以使用您的算法(但要快约400倍),因为它意识到19和20是相对素数,因此任何解决方案必须是19 * 20的倍数:< / p>

UPTO = 300000000
STEP = 19 * 20

for i in xrange(STEP, UPTO, STEP):
    if any(i % div for div in xrange(6, 19)):
        continue
    else:
        print("Solution: {}".format(i))
        break

在我的机器上运行大约0.94秒(对于#34;良好&#34;算法= 0.0000249秒=再大约快37,000倍!)。