我正在学习Python(我有其他语言的背景知识,尤其是C等),并且我试图编写一些简单的函数来增强我在Python教程中阅读的内容。特别是,这是我尝试确定一个是否为整数的函数的方法:
def isComposite(n):
"""Straight loop."""
for x in range(2, int(math.sqrt(n)) + 1):
if n % x == 0:
return x
return False
_PrimeList = [2]
def isCompPL(n):
"""Recursive version."""
for x in _PrimeList:
if n % x == 0:
if n == x:
return False
return x
for x in range(_PrimeList[-1], int(math.sqrt(n)) + 1):
if not isCompPL(x):
if x > _PrimeList[-1]:
_PrimeList.append(x)
if n % x == 0:
return x
return False
def isCompSR(n):
"""Serialized recursive version."""
l = [n]
while (math.sqrt(l[0]) > _PrimeList[-1]):
l.insert(0, int(math.sqrt(l[0])))
l.insert(0, _PrimeList[-1] + 1)
while (len(l) > 2):
q = l.pop([0])
for x in range(q, l[0]):
for y in _PrimeList:
if x % y == 0:
break
else:
_PrimeList.append(x)
return isCompPL(n)
当isComposite(n)
以isCompPL(n)
开始时, isCompSR(n)
比_PrimeList
或[2]
快几个数量级。当_PrimeList
包含所有素数到n
的平方根时,则isCompPL(n)
和isCompSR(n)
都会赶上,并且可能比isComposite(n)
快,但不是明显地如此。更令我惊讶的是,如果我呼叫isCompSR(511111111111)
,则后续呼叫isCompSR(1111111111111)
仍然比呼叫isComposite(1111111111111)
慢得多,而在第一次呼叫{{1 }}。
Python的列表操作中是否存在隐藏的东西,这些东西使得这些尝试在优化方面不成功,还是仅仅是我添加了很多额外的主要测试,而我需要以某种方式减少这一部分?
答案 0 :(得分:0)
两个主要评论者(@ alexis,@ juanpa.arrivillaga)都对我编写的代码进行了正确的评估(评估了太多数字,以低效的方式使用列表数据类型),并且在两方面都有改进,更新后的“序列化递归”功能总体上要快得多,并且比_PrimeList
初始化后的“直线循环”版本要快得多。 isCompSR(n)
的当前版本如下:
def isCompSR(n):
"""Serialized recursive version."""
for x in _PrimeList:
if n % x == 0:
return x
l = [n]
while (math.sqrt(l[-1]) > _PrimeList[-1]):
l.append(int(math.sqrt(l[-1])))
l.append(_PrimeList[-1] + 1)
while (len(l) > 2):
q = l.pop()
for x in range(q, l[-1]):
if n % x == 0:
return x
for y in _PrimeList:
if x % y == 0:
break
else:
_PrimeList.append(x)
return False
请注意,此代码现在将在除n
的第一个质数处“删除”,而不是像以前一样继续处理直到math.sqrt(n)
的所有数字。另外,现在可以通过调用l
和.append
而不是在开头插入和弹出来更适当地使用列表.pop()
。