Python减少功能混淆

时间:2014-03-31 15:30:14

标签: python primes reduce

我试图理解python如何减少内置方法的工作原理,所以尝试了一些我能想到的简单样本。但这是一个我不太明白的例子,如果有人能给我一些提示,我会非常感激。

所以我有一个数组,它有几个这样的素数

>>> arr
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199]

我尝试使用像这样的reduce函数

>>> reduce(lambda x, y: is_prime(x) and is_prime(y), arr)
False

我不太明白为什么这里的答案是False而不是True,因为我只是想要is_prime的所有答案,并且数组中的所有数字都是prime,它会为每个is_prime返回True。

我还检查了数组中的每个数字实际上都为我的is_prime()

返回了True
>>> for n in arr:
...     if not is_prime(n):
...         print n
...
>>>

我一定在这里遗漏了什么,有人可以帮忙吗?感谢。

4 个答案:

答案 0 :(得分:4)

考虑一下你逐渐减少的价值观:

>>> reduce(lambda x,y: isprime(x) and isprime(y), [2])
2

只有一个元素,因此reduce为我们提供了第一个元素。

>>> reduce(lambda x,y: isprime(x) and isprime(y), [2, 3])
True

有道理:两者都是素数。

>>> reduce(lambda x,y: isprime(x) and isprime(y), [2, 3, 5])
False

这个看起来很奇怪,但这是因为你实际上在调用

isprime(True) and isprime(5)

因为True是最后一个值,True的{​​{1}}值为1:

int

>>> int(True) 1 != reduce

答案 1 :(得分:1)

的结果
is_prime(x) and is_prime(y)

将是一个布尔值,当前表达式的结果将在下一次迭代中被提供给lambda函数x

因此,如果任何is_prime次调用返回False,则整个结果将变为False。因为

第一次迭代:

(Default Value & First Value)

第二次迭代:

(Previous Result & Current Value)

由于它是一系列和操作,如果它们中的任何一个是False,整个表达式将被评估为False

答案 2 :(得分:0)

lambda中的第一个参数(x)是累计值,第二个(y)是迭代值。尝试:

reduce(lambda x, y: x and is_prime(y), arr, True)

因此x将被以 True (初始累积值)开始的累计值替换,因此True和is_prime(2)= True,因此True传递给下一次迭代...

尝试检查是否所有都是奇数:

>>> arr = [3, 5, 7, 11, 15]
>>> reduce(lambda x, y: x and y%2!=0, arr, True)
True

现在我将定义一个函数来打印中间累积值:

>>> def xxx(y):
...    print y
...    return y
...
>>> reduce(lambda x, y: xxx(x) and y%2!=0, arr, True)
True
True
True
True
True
True
>>> arr = [3, 5, 7, 12, 15]
>>> reduce(lambda x, y: xxx(x) and y%2!=0, arr, True)
True
True
True
True
False
False
>>>

更明确地命名这样的变量:

reduce(lambda accumulated, number: accumulated and is_prime(number), arr, True)

答案 3 :(得分:0)

传递给reduce()的双参数函数应该返回一个与输入类型相同的值,将两个值“减少”为一个值; reduce()注意重复应用该函数,将整个输入可迭代的减少为单个值。

经典示例:使用lambda x,y:x+y的输入总和。

如果您希望如果列表中的每个数字都是素数,则结果为true,您可以使用内置的all()函数:

they_are_all_primes=all((is_prime(x) for x in [2,3,5]))