过滤器是否有一种方法可以一次导出“列表”一个元素?

问题描述 投票:0回答:1

在关于素数的练习中,我发现

filter
本身不返回列表,我需要这样做:

list(filter())

获取该列表。

我做了两次练习,一次使用 for 循环:

def is_prime_for(n:init):
    if n <=3:
        return True
    else:
        m=list(range(2,n//2+1))     #+1 on the range for evade a bad result if 'n==4'    
    for i in m:
        if n % i == 0:
            return False
    else:
        return True
value = 864203                     
print(is_prime_for(value))

其他时间与

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                 #Same prime number that i found on google
print(is_prime(value))

后来我重新使用高阶函数的代码,发现我的“紧凑”

filter
lambda
函数需要比函数执行时间多一倍的时间,并且使用“False”数字(例如一个数字可以除以 2)。

我可以理解双倍时间,因为它会遍历列表两次而不是一次,但在“False”数字的情况下,我认为 filter() 会给我一个空列表,直到第一个数字出现,但这不是这种情况下,列表为“空”,直到过滤结束。

有谁知道一种方法来“更新”过滤的项目列表,而不是在过滤结束时一次列出?

这是我现在的代码,具有显示执行时间的高阶函数:

import time  
  
def timeis(func):   #Decorator that reports the execution time.
    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 on the range for evade a bad result if '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           #A prime number that i found on google
#print(is_prime(value))    #That is used for prove the value find on google for no "false" positives
is_prime(value)
is_prime_for(value)

这就是输出:

is_prime 0.06304740905761719
is_prime_for 0.02378678321838379
python filter lambda
1个回答
0
投票

这里有一些需要改进的地方:

  • 无需将

    list
    应用于
    filter
    的第二个参数的范围。
    filter
    只需要一个可迭代作为第二个参数,所以范围就可以了。

  • 当目标是验证

    list
    不产生任何结果时,无需将
    filter
    应用于
    filter
    的结果。在这种情况下,您可以使用
    any
    而不是
    filter

  • 以下模式是需要摆脱的:

    if <boolean-expression>:
        return True
    else:
        return False
    

    相反,只需返回布尔表达式的值。

  • 通过使其内联执行模运算,您为

    is_prime_for
    提供了一点优势,而
    is_prime
    必须为此调用一个函数。为了有一个平等的竞争环境,
    is_prime
    也应该排队执行该操作。

  • 两种实现都可以通过将除数搜索限制为

    n
    的平方根来做得更好。任何更大的除数都会有一个更小的对应部分。例如,如果
    n
    n//2
    作为除数,那么它也有 2 作为除数,所以不需要同时测试两者。

这给我们带来了这个版本的代码:

@timeis
def is_prime(num: int):
    return any(num%x for x in range(2, int(num**0.5+1.01)))

进一步改进是可能的

© www.soinside.com 2019 - 2024. All rights reserved.