Python 我的主要过滤代码有什么问题?它赢了';不要返回正确的列表
我编写了一个函数Python 我的主要过滤代码有什么问题?它赢了';不要返回正确的列表,python,python-3.x,recursion,primes,Python,Python 3.x,Recursion,Primes,我编写了一个函数filter\u primes,它应该(恰当地)从给定列表中过滤出素数,并输出一个新的素数列表。当我运行这个示例时,我得到了>>[9]。 我的脑子乱七八糟。有人能给我指出正确的方向吗 n = 2 def is_prime(num): global n if num%n != 0 and n<num: n = n + 1 is_prime(num) elif n == num: return True else: return
filter\u primes
,它应该(恰当地)从给定列表中过滤出素数,并输出一个新的素数列表。当我运行这个示例时,我得到了>>[9]。我的脑子乱七八糟。有人能给我指出正确的方向吗
n = 2
def is_prime(num):
global n
if num%n != 0 and n<num:
n = n + 1
is_prime(num)
elif n == num:
return True
else:
return False
def filter_primes(list1):
list2 = []
for i in list1:
if is_prime(i):
list2.append(i)
print(list2)
filter_primes([7, 9, 3, 9, 10, 11, 27])
n=2
def是_prime(num):
全球n
如果数量为%n!=0和n问题出在is_prime
函数中。由于您是以递归方式执行此操作,因此希望将其分为:
- 处理基本情况:
- 你会发现一个
n
平均除以num
,那么num
就不是素数了
- 最后得到的
n
大于num
,则num
为素数
- 否则,使用
n+1
递归调用函数,并返回该值
使用全局n(每次使用新的较大值时都会被覆盖)的一种方法是使用is_prime(n有一个默认的起始值)
比如说,
def is_prime(num, n=2):
if n >= num: # This could be made into sqrt(num) if you're trying to optimize this
return True
if num % n == 0:
return False
return is_prime(num, n+1)
问题出在is_prime
函数中。由于您是以递归方式执行此操作,因此希望将其分为:
- 处理基本情况:
- 你会发现一个
n
平均除以num
,那么num
就不是素数了
- 最后得到的
n
大于num
,则num
为素数
- 否则,使用
n+1
递归调用函数,并返回该值
使用全局n(每次使用新的较大值时都会被覆盖)的一种方法是使用is_prime(n有一个默认的起始值)
比如说,
def is_prime(num, n=2):
if n >= num: # This could be made into sqrt(num) if you're trying to optimize this
return True
if num % n == 0:
return False
return is_prime(num, n+1)
我解决这个问题的方法是在IDE(IntelliJ)中打开代码,然后使用集成的调试器逐行遍历代码。这将帮助你想象正在发生的事情。否则,请尝试打印出函数内的变量
第一个问题是您正在使用global n
。这对于第一个数字7
,效果非常好,但是对于第二个数字9
,此数字不会被重置。因此,is_prime(9)
只针对8
的除法进行测试(这就是它返回true的原因)
这可能在循环中完成,而不是使用递归,但由于您使用的是递归,n
(作为内部状态)可以通过将其作为带有默认值的函数参数传递来处理。这将为n的每个顶级调用重置n
另外,当您递归调用is_prime()
时,您需要return is_prime()
以确保当您将原始调用方放回到堆栈底部时,从堆栈顶部返回的布尔值会返回
您的代码意外地为is_prime(9)
工作,因为您的逻辑只测试了8,因此可以返回而不重复
以下是工作代码:
def为素数(num,n=2):
如果数量为%n!=0和n
此外,您可能会发现阅读一下素数搜索算法
也很有趣
一些简单的优化:
- 除2外,所有素数都是奇数(因此可以立即返回False)
- 埃拉托斯烯的筛进一步扩大了这一范围
- 从技术上讲,您只需搜索到
sqrt(num)
- 请阅读
备忘录(也称为动态编程),因为您可以缓存以前函数调用的结果
- 为您的函数添加python类型的提示和编写文档(一个月后返回代码时,您未来的自己会感谢您)
考虑一个新用例:
- 生成整个素数序列(您将在此处开始注意性能问题)
- 在IDE中添加计时器或使用探查器。比较代码运行的速度,尤其是对于大的数字。这些建议的优化是否加快了速度
我解决这个问题的方法是在IDE(IntelliJ)中打开代码,然后使用集成的调试器逐行检查代码。这将帮助你想象正在发生的事情。否则,请尝试打印出函数内的变量
第一个问题是您正在使用
global n
。这对于第一个数字7
,效果非常好,但是对于第二个数字9
,此数字不会被重置。因此,is_prime(9)
只针对8
的除法进行测试(这就是它返回true的原因)
这可能在循环中完成,而不是使用递归,但由于您使用的是递归,n
(作为内部状态)可以通过将其作为带有默认值的函数参数传递来处理。这将为n的每个顶级调用重置n
另外,当您递归调用is_prime()
时,您需要return is_prime()
以确保当您将原始调用方放回到堆栈底部时,从堆栈顶部返回的布尔值会返回
您的代码意外地为is_prime(9)
工作,因为您的逻辑只测试了8,因此可以返回而不重复
以下是工作代码:
def为素数(num,n=2):
如果数量为%n!=0和n