条件列表推导式

7

我希望能更好地理解列表推导的工作原理。我有一个函数,如果一个数字是质数,则返回true或false(我在论坛上找到的,但忘记了在哪里):

import math

def is_prime(n):
    if n % 2 == 0 and n > 2: 
        return False
    for i in range(3, int(math.sqrt(n)) + 1, 2):
        if n % i == 0:
            return False
    return True

如果我运行:

[x for x in range(2, num) if is_prime(x)]

我得到了期望的结果。
[2, 3, 5, 7, 11, 13, 17, 19]

在试图将整个函数转换为列表推导式时,我想到了以下内容:

[x if not (x%2==0 and x > 2) else x for x in range (2, num) 
     for i in range(3, int(x**(1/2))+1, 2) if not (x%i==0)]

生成以下内容:

[10, 11, 13, 14, 16, 17, 19]

我不确定我的错误在哪里,希望得到一些帮助。实际上,在这种情况下,我认为使用函数更好,但是像我说的,我正在尝试理解列表推导式及其功能。


@Wright:那只返回奇数并排除2。OP还排除可被3整除的数字。 - Prune
我认为这太多了,无法压缩到列表推导式中。练习时可以这样做,但是当其他人需要阅读时,请不要创建类似的东西。 - Paul Rooney
仅供娱乐,我计时了每个版本:函数[x for x in range(2, num) if is_prime(x)]的版本为9.01秒每次循环;@Julien版本(稍作修改):12.8秒每次循环和@Harshit Garg版本:44.4秒每次循环 - Infinity Cliff
3个回答

7
你可以这样做:
[n for n in range(2, num) if n % 2 != 0 and n > 2 and all(n % i != 0 for i in range(3, int(math.sqrt(n)) + 1, 2))]

尽管只是为了一句话而写的代码不一定是好事。在我看来,像您这样使用质数测试函数更好...
注意:您的尝试中不起作用的原因是您修改了外部列表推导式的逻辑。您仍然希望像这样有一个结构:[n for n in range(...) if (expression testing if n is prime)]

1
我稍微修改了一下,将“2”包含在列表中:[n for n in range(2, num) if (n % 2 != 0 or n ==2) and all(n % i != 0 for i in range(3, int(math.sqrt(n)) + 1, 2))]。不确定我是否完全理解答案为什么可以排除“2”,但我会再仔细看看。 - Infinity Cliff
我同意使用函数是更好的方法。这是一个练习,让我尝试更好地理解列表推导式。我想,如果我能理解一些复杂的东西,它将有助于我理解更简单、更合适的用法。 - Infinity Cliff
好眼力,我确实忘记把n>2改为n==2的否定形式。 - Julien

0
主要问题是您正在进行复杂的翻译。尝试简化原始条件,使其返回“x if x==2, else x ...”,就像您已经做的那样。我在这里只是给你一个提示;从你已经做的事情来看,我认为你可以想出来。
如果不行,尝试简化“else”表达式,以便您了解该从句的逻辑。然后我相信您会明白的。您做得很好。

0

以上代码存在逻辑错误。1/2的计算结果为0,而不是0.5。要想得到0.5的结果,可以使用0.5或者1/2.0或者1.0/2。

此外,它没有考虑2作为一个特殊情况。因为(for i in range(3, int(x**(1/2.0))+1, 2) if not (x%i==0))没有被执行。

for i in range(3, int(x**(1/2.0))+1, 2) if not (x%i==0)也是一个逻辑错误,因为每当这个条件为真时,就会导致多个条目被添加。

正确的方法应该是:

[x for x in range (2, num) if x == 2 or (x > 2 and x % 2 == 1 and len([i for i in range(3, int(x**(1/2.0))+1, 2) if x%i == 0 ])==0)]

我正在使用Python 3,(1/2) 对我来说评估为 0.5,不确定你提到的问题是否出现在旧版本的Python中,但是,你的答案确实有效。 - Infinity Cliff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接