简体   繁体   English

编译时Python卡住

[英]Python gets stuck when compiling

I have written a program that finds the smallest number that has every number from 1 to 20 as a multiple. 我编写了一个程序,查找最小的数字,该数字的每个数字都从1到20为整数。 My code in C++ works perfectly and finds the correct answer: 我的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;

        }

    }

}

However, the same program in Python - which works when finding the smallest number with all of 1 to 10 as multiples, but only if the range being searched is smaller (it works with 5000000) - simply will not compile. 但是,Python中的同一程序(仅当查找的范围是1到10的整数倍时才有效,但仅当搜索的范围较小时才有效)(仅适用于5000000),将无法编译该程序。 I goes on forever and I have to close the Terminal window. 我一直坚持下去,必须关闭终端窗口。

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

I am using Mac OS X Mavericks, if this is relevant. 如果相关,我正在使用Mac OS X Mavericks。

Edit: I have tried switching to xrange, but this regrettably makes no difference. 编辑:我曾尝试切换到xrange,但遗憾的是没有区别。

Edit2: I left it on in the background - it did in fact just take about 14 minutes to run! Edit2:我把它留在后台-实际上它只需要14分钟即可运行! I apologise, I should have done this in the first instance. 抱歉,我应该首先这样做。

I guess you are using Python 2. 我想您正在使用Python 2。

Your problem is this: 您的问题是这样的:

range( 1, 300000000 )

You are building a list of 300000000 Python int objects. 您正在建立一个300000000个Python int对象的列表。 If we assume that ints in Python are 4-bytes (which is tremendously false), then you are allocating 300000000 × 4 = 1200000000 bytes = 1 GB. 如果我们假设Python中的整数是4字节(这是非常错误的),那么您将分配300000000×4 = 1200000000字节= 1 GB。

You should replace it with the following: 您应该将其替换为以下内容:

xrange( 1, 300000000 )

The advantage of xrange is that it does not pre-allocate all the Python ints in advance. xrange的优点是它不会预先预先分配所有Python int。 See the documentation of xrange for more information: 有关更多信息,请参见xrange文档:

The advantage of xrange() over range() is minimal [...] except when a very large range is used on a memory-starved machine [...] xrange()优于range()的优势是最小的,除非在内存不足的计算机上使用了非常大的范围[...]

With Python 3 this problem does no longer exist, because range has been removed and xrange has been renamed to range . 使用Python 3时,此问题不再存在,因为range已被删除并且xrange已重命名为range

Note that this will solve any memory error you would encounter. 请注意,这将解决您遇到的所有内存错误。 This won't solve the problem of using a bad, slow algorithm. 这不会解决使用不良的慢速算法的问题。 Python is not really speedy when dealing with numbers (but also other languages will perform slowly when using huge numbers). 在处理数字时,Python并不是真的很快(但是在使用大量数字时,其他语言的执行也会很慢)。

What do you mean "compile"? 你是什​​么意思“编译”? How are you compiling Python code? 您如何编译Python代码?

Try using xrange() 尝试使用xrange()

If this is python 2 then you really need to change the range to xrange . 如果这是python 2,那么您确实需要将range更改为xrange range works by creating a list of the size specified which you are then iterating over item by item. range通过创建指定大小的列表进行工作,然后逐项迭代。 However in this case you don't need the list itself, only the indexes which were contained in that list. 但是,在这种情况下,您不需要列表本身,仅需要该列表中包含的索引。 So you should prefer xrange because it is a generator which means that it can iterate without creating a list in memory. 因此,您应该首选xrange因为它是生成器,这意味着它可以迭代而无需在内存中创建列表。 This will save your program from having to create a really large list which will take up a lot of memory. 这将使您的程序不必创建一个非常大的列表,而这将占用大量内存。

Note that in Python 3 range has the same behaviour that Python 2 xrange had. 请注意,在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

Also Python is an interpreted language, there is no compile step like there is in c++. 同样,Python是一种解释型语言,没有像c ++那样的编译步骤。 What you are seeing is just a slow running time. 您所看到的只是运行时间缓慢。

Your Python program is not wrong , it is just very very slow because you are using a very bad algorithm. 您的Python程序没有 ,它只是非常非常慢,因为您使用的算法很糟糕。

Try this instead: 尝试以下方法:

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))

Edit: alternatively, you can use your algorithm (but make it about 400x faster) by realizing that 19 and 20 are relatively prime, therefore any solution must be a multiple of 19 * 20: 编辑:或者,您可以通过意识到19和20是相对质数来使用算法(但使其速度提高约400倍),因此任何解决方案都必须是19 * 20的倍数:

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

which runs in about 0.94 s on my machine (vs. 0.0000249 s for the "good" algorithm == about 37,000 times faster again!). 它在我的机器上运行约0.94 s(“好”算法则为0.0000249 s,=再次快了约37,000倍!)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM