[英]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并不是真的很快(但是在使用大量数字时,其他语言的执行也会很慢)。
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.