You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中filter能否逐个输出元素?如何优化素数判断性能?

素数判断中的filter性能问题与优化实践

在素数判断练习中,我发现Python的filter函数并不直接返回列表,必须通过list(filter())才能得到对应的列表对象。我分别用两种方式实现了素数判断逻辑:

初始实现方案

1. for循环实现

def is_prime_for(n: int):
    if n <= 3:
        return True
    else:
        m = list(range(2, n//2 + 1))     # +1 是为了避免n==4时出现错误结果
    for i in m:
        if n % i == 0:
            return False
    else:
        return True
value = 864203                     
print(is_prime_for(value))

2. filter+lambda实现

def is_divisible(num1: float, num2: float):
    if num1 % num2 == 0:
        return True
    else:
        return False

def is_prime(num: int):
    if list(filter(lambda x: is_divisible(num, x), list(range(2, num//2 + 1)))) != []:
        return False
    else:
        return True
value = 864203                 # 从谷歌找到的素数
print(is_prime(value))

性能差异与疑问

通过带计时装饰器的测试代码对比发现,filter+lambda实现的函数执行时间是for循环版本的两倍,判断非素数时性能差距更明显。我理解这是因为前者需要遍历整个序列完成过滤后才生成列表,而for循环在找到第一个能整除的数时就直接返回结果。我原本以为判断非素数时,filter会在找到第一个符合条件的元素时就返回结果,而非等全部过滤完成,所以想请教:有没有办法让filter逐个输出过滤后的元素,不用等待整个过滤流程结束?

计时测试代码

import time  

def timeis(func):   # 统计函数执行时间的装饰器
    def wrap(*args, **kwargs): 
        start = time.time() 
        result = func(*args, **kwargs) 
        end = time.time() 
        
        print(func.__name__, end - start) 
        return result 
    return wrap 

def is_divisible(num1: float, num2: float):
    if num1 % num2 == 0:
        return True
    else:
        return False
    
@timeis
def is_prime(num: int):
    if list(filter(lambda x: is_divisible(num, x), list(range(2, num//2 + 1)))) != []:  # +1 避免n==4时出错
        return False
    else:
        return True
    
@timeis
def is_prime_for(n : int = 2):
    if n <= 3:
        return True
    else:
        m = list(range(2, n//2 + 1))
    for i in m:
        if n % i == 0:
            return False
    else:
        return True 

value = 864203           # 谷歌找到的素数
# print(is_prime(value))    # 验证该数确实是素数,避免误判
is_prime(value)
is_prime_for(value)

测试输出结果

is_prime 0.06304740905761719
is_prime_for 0.02378678321838379

优化后的实现与测试结果

经过优化后的代码如下,主要优化点包括:将遍历范围缩小到目标数的平方根(因为若n有大于平方根的因数,则必然存在对应的小于平方根的因数),使用any()/all()替代filter(这两个函数会在满足条件时立即返回,无需生成完整列表):

import time

def timeis(func):  # 统计函数执行时间的装饰器
    def wrap(*args, **kwargs): 
        start = time.time() 
        result = func(*args, **kwargs) 
        end = time.time() 
        
        print(func.__name__, end - start) 
        return result 
    return wrap 

def is_divisible(num1: float, num2: float):
    if num1 % num2 == 0:
        return True
    else:
        return False

@timeis
def is_prime(num: int):
    if any(is_divisible(num, x) for x in range(2, int(num**0.5 + 1.01))):   # 参考Trincot的回答与OneCricketeer的评论优化了数学逻辑
        return False
    else:
        return True

@timeis
def is_prime_all(num: int):                           # Trincot提供的实现
    return all(num % x for x in range(2, int(num**0.5 + 1.01)))

@timeis
def is_prime_all_mod(num: int):                       # Trincot实现的修改版,判断非素数时更快
    return all(num % x for x in range(2, num//2 + 1))

@timeis
def is_prime_for(n : int = 2):       # 参考Trincot的回答优化了数学逻辑
    if n <= 3:
        return True
    else:
        m = range(2, int(n**0.5 + 1.01))
    for i in m:
        if n % i == 0:
            return False
    else:
        return True 

@timeis
def is_prime_while(n : int = 2):    # 参考Trincot的回答优化了数学逻辑
    if n <= 3:
        return True
    else:
        x = int(n**0.5 + 1.01)
        i = 2
        while i < x:
            if n % i == 0:
                return False
            i += 1
        else:
            return True 

# value = 28122221                 # 谷歌找到的素数
value = 28122222                # 用于测试的非素数
# print(is_prime(value))  
is_prime(value)
is_prime_all(value)
is_prime_all_mod(value)
is_prime_for(value)
is_prime_while(value)

素数测试输出

is_prime 0.00029087066650390625
is_prime_all 0.0001399517059326172
is_prime_all_mod 0.607919454574585
is_prime_for 0.0001266002655029297
is_prime_while 0.00017380714416503906

非素数测试输出

is_prime 1.0013580322265625e-05
is_prime_all 7.152557373046875e-06
is_prime_all_mod 1.6689300537109375e-06
is_prime_for 1.1920928955078125e-06
is_prime_while 4.76837158203125e-07

内容的提问来源于stack exchange,提问作者bola8divad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 20:44:54