Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 计算素数和的Lambda函数_Python_List_Lambda_Filter_Primes - Fatal编程技术网

Python 计算素数和的Lambda函数

Python 计算素数和的Lambda函数,python,list,lambda,filter,primes,Python,List,Lambda,Filter,Primes,在编写一个python程序来计算2到n(包括2到n)之间的素数之和时,我得到了一个错误“生成器不可调用” 谁能帮我解决这个错误,或者建议我在这里遗漏了什么 n = int(input()) sum = 0 sum = sum(list(filter((lambda n: n%y != 0 for y in range(2, n)), range(2, n+1)))) print(sum) 你的解决方案几乎是正确的。但是您需要在lambda函数中使用all,因为您需要所有n%y!=0声明为真

在编写一个python程序来计算2到n(包括2到n)之间的素数之和时,我得到了一个错误“生成器不可调用”

谁能帮我解决这个错误,或者建议我在这里遗漏了什么

n = int(input())

sum = 0
sum = sum(list(filter((lambda n: n%y != 0 for y in range(2, n)), range(2, n+1))))

print(sum)

你的解决方案几乎是正确的。但是您需要在lambda函数中使用
all
,因为您需要所有
n%y!=0
声明为真:

sum(list(filter((lambda n: all(n%y != 0 for y in range(2,n))), range(2,n+1))))
正如评论中指出的,您可以通过只检查不大于数字平方根的除数来提高代码的效率:

import math
sum(list(filter((lambda n: all(n%y != 0 for y in range(2,int(math.sqrt(n))+1))), range(2,n+1))))
解释

  • n%y!=范围(2,n)中y的0
    是生成器,而不是布尔值
  • all(n%y!=0表示范围(2,n)中的y)
    是对应于
    n%2!=0和n%3!=0和。。。和n%(n-1)!=0

稍微清洁的版本:

n = int(input())
nums = range(2, n + 1)
for i in range(2, n + 1):
    nums = list(filter(lambda x: x == i or x % i, nums))

print(sum(nums))

您也可以通过列表理解这样写:

from math import sqrt, floor

sum(( p 
      for p in range(2, n+1) 
      if all( p%q != 0 for q in range(2, floor(sqrt(p))+1) ) ))
你不需要检查所有的数字,只需要检查数字的平方根

示例:通过检查10%2==0或10%5==0,可以发现10=2*5不是素数。对于平方根极限,你只需要检查到3,但这很好,因为你已经看到了2,并且定义10为非素数

如果这个应用程序是供您研究的,您可能需要检查以查找素数,这被认为是查找小素数的最有效方法之一

然而,如果你只需要找到素数并求和,你可以使用像..这样的库

1。第一个错误:“TypeError:“generator”对象不可调用”

由于传递给
过滤器
内置方法a生成器,您用括号“覆盖”了
lambda
方法,因此会出现此错误:

filter((lambda n: n%y != 0 for y in range(2,n)), range(2,n+1))
解决方案:“揭开”括号

filter(lambda n: n%y != 0 for y in range(2,n), range(2,n+1))
2。第二个错误:“SyntaxError:生成器表达式必须为空。” 括号中的“

lambda n: n%y != 0 for y in range(2,n)
n = int(input())

n_prime_sum = 0
n_prime_sum = sum(list(filter(lambda n: all(n%y != 0 for y in range(2,n)), range(2,n+1))))
n_prime_sum
# n = 10
错误很明显:
n%y!=范围(2,n)中y的0是一个生成器,需要用括号括起来,
在这里,您需要测试该数字是否为素数,因此您需要检查生成器中的所有值是否为
True

解决方案:使用内置方法
all

lambda n: all(n%y != 0 for y in range(2,n))
3。最后一个错误:“TypeError:“int”对象不可调用”

这是因为您正在为变量
sum
使用
sum
内置方法名,因此
sum
不再是内置方法,而是一个整数

解决方案:变量的另一个名称:

n_prime_sum = 0

这是您的代码和修复程序

lambda n: n%y != 0 for y in range(2,n)
n = int(input())

n_prime_sum = 0
n_prime_sum = sum(list(filter(lambda n: all(n%y != 0 for y in range(2,n)), range(2,n+1))))
n_prime_sum
# n = 10
输出:

17
17

此外,您还可以定义一个生成所有基本btw 2和n(包括)的函数,然后在此函数上应用
sum
内置方法:

# original code by David Eppstein, UC Irvine, 28 Feb 2002
# with comments by Eli Bendersky, https://stackoverflow.com/a/568618

def gen_primes(n):
    """Much more efficient prime generation, the Sieve of Eratosthenes"""

    D = {}

    q = 2   # The running integer that's checked for primeness

    while q <= n:
        if q not in D:
            # q is a new prime.
            # Yield it and mark its first multiple that isn't
            # already marked in previous iterations
            # 
            yield q
            D[q * q] = [q]
        else:
            # q is composite. D[q] is the list of primes that
            # divide it. Since we've reached q, we no longer
            # need it in the map, but we'll mark the next 
            # multiples of its witnesses to prepare for larger
            # numbers
            for p in D[q]:
                D.setdefault(p + q, []).append(p)
            del D[q]

        q += 1

n = int(input())
n_prime_sum = sum(gen_primes(n))
print(n_prime_sum)
# n = 10

函数
gen_prime
的大部分代码来自嗯,在我的想象中,这种方法是最佳的

  • 仅用已知素数(而不是每个数)除
  • 到给定数字的平方根为止

然后是丑陋化,使之成为
lambda
部分

isprime=lambda n:all(n%p!=0 for p in primes)
工作正常,但它忽略了
sqrt
magic,然后

isprime=lambda n:all(n%p!=0 for p in (p for p in primes if p<=int(math.sqrt(n))))

我仍然不喜欢将所有素数与S相比较,在中间停止可能更有效,得到一个用<代码>索引(下一个(…))< /代码>的片段可以做到:

isprime=lambda n:all(n%p!=0 for p in primes[:(lambda s:primes.index(next(p for p in primes if p>s)))(int(math.sqrt(n)))])
只是
next()
index()
遍历列表的一部分两次仍然很难看

然后是外部循环,我将使用
functools
中的
reduce()
,因为reduce的累加器可能是实际的素数列表,然后它将不是一个单独的变量

第0步将以最简单的方式进行,仍然有变量
primes
,但使用元组的可怕技巧,
(do,some,things,result)[3]
将执行这些操作,并对
结果进行评估:

primes=[2]
isprime=lambda n:all(n%p!=0 for p in primes[:(lambda s:primes.index(next(p for p in primes if p>s)))(int(math.sqrt(n)))])
maxn=19
ps=functools.reduce(lambda primes,n:(primes.append(n) if isprime(n) else None,primes)[1],range(3,maxn+1),primes)
print(ps)
print(primes)
print(sum(primes)) # ps and primes are the same list actually
然后确定怪物:

import math
import functools

plist=lambda maxn:functools.reduce(lambda primes,n:(primes.append(n) if (lambda n:all(n%p!=0 for p in primes[:(lambda s:primes.index(next(p for p in primes if p>s)))(int(math.sqrt(n)))]))(n) else None,primes)[1],range(3,maxn+1),[2])

primes=plist(19)
print(primes)
print(sum(primes))
测试:
输出:


附带的信息是:lambdas可能很有用,但实际上您不必总是使用它们。

在阅读了所有答案并尝试/测试了自己之后,我重新设计了答案,您可以根据需要进行修改:

# get the user input
n = int(input())

from functools import reduce

# create a list with all the primes within the input number range
n_prime = range(2, n + 1)
for i in range(2, n + 1):
    n_prime = list(filter(lambda x: x == i or x % i, n_prime))

# print the list of primes obtained from above
print(n_prime)

# let's add all these numbers in the above list and print the summed value
sum_n_prime = reduce(lambda x, y : x + y, n_prime)
print(sum_n_prime)

传递给
过滤器的第一个参数是生成器
(lambda n:n%y!=0表示范围(2,n))中的y
,但应该是一个函数,其中一个参数返回True或False。命名错误,
sum
是一个内置名称不起作用,因为你在循环的每次迭代中都覆盖
nums
。请用输入
100
运行代码,你应该得到
1060
,这是正确的答案。同意,但用7运行它,你会得到10(假),而不是17(正确)。错过了“包含”部分,修复了它。你可以应用常见的“技巧”对于只运行平方根的内部循环,类似于范围(2,int(math.sqrt(n))+1)中y的
@tevemadar当然,我只是尊重用户的解决方案并修复了它:)您可以添加改进的解决方案。@WillNess确定。我应该加哪一个?有很多算法,不仅仅是那个些使用暴力的算法……还有sqrt,不是吗?这是一个开始。对于“小”(比如12位数以下)的数字,埃拉托什尼筛是最有效的。试用除法的筛选——没有那么多。您可能应该以某种方式对开头代码中的
isprime()
的脆弱性进行评论,也就是说,如果我们在
maxn=19
之后插入调用
isprime(19)
,它将返回false(或其他一些错误,如未指定的返回值)。@WillNess是的,谢谢,您是对的。起初我是这么想的,但后来我完全忘记了,我只专注于一艘邮轮(这艘邮轮是“安全的”,因为一切都发生在“里面”)。还有,t
[2, 3, 5, 7, 11, 13, 17, 19]
77
# get the user input
n = int(input())

from functools import reduce

# create a list with all the primes within the input number range
n_prime = range(2, n + 1)
for i in range(2, n + 1):
    n_prime = list(filter(lambda x: x == i or x % i, n_prime))

# print the list of primes obtained from above
print(n_prime)

# let's add all these numbers in the above list and print the summed value
sum_n_prime = reduce(lambda x, y : x + y, n_prime)
print(sum_n_prime)