简体   繁体   English

条件列表理解

[英]Conditional list comprehension

I am trying to gain a better understanding of how list comprehensions work. 我试图更好地理解列表推导如何工作。 I have the following function that returns true or false if a number is prime (which I found somewhere on the forum but cant remember where): 我有以下函数返回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

if I run: 如果我跑:

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

i get the desired result 我得到了理想的结果

[2, 3, 5, 7, 11, 13, 17, 19]

in trying to convert the whole function to a list comprehension I came up with: 在尝试将整个函数转换为列表理解时,我提出了:

[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)]

which produces: 产生:

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

not sure where I am going wrong and would appreciate some help. 不知道我哪里出错了,并希望得到一些帮助。 In truth I think it is better to use the function in this case, but like I said I am trying to understand the list comprehension and its capabilities. 事实上,我觉得在这种情况下使用函数会更好,但就像我说的那样,我试图理解列表理解及其功能。

You can do this: 你可以这样做:

[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))]

although one liner just for the sake of it is not necessarily a good thing. 虽然只是为了它的一个班轮不一定是好事。 IMO using a prime tester function like you do is better... IMO使用像你这样的主要测试仪功能更好......

NOTE: what doesn't work in your try is that you modified the logic of your outer list comprehension. 注意:在您的尝试中不起作用的是您修改了外部列表理解的逻辑。 You still want a structure like [n for n in range(...) if (expression testing if n is prime)] . 你仍然想要一个像[n for n in range(...) if (expression testing if n is prime)]

The main problem is that you're making a convoluted translation. 主要问题是你正在进行复杂的翻译。 Try simplifying the original condition so that you return "x if x==2, else x ..." as you've already done. 尝试简化原始条件,以便返回“x if x == 2,else x ...”,就像您已经完成的那样。 I'm just giving you a leading hint here; 我只是在这里给你一个领先的暗示; from what you've done already, I think you can figure it out. 从你已经完成的事情来看,我认为你可以搞清楚。

If not, try simplifying the "else" expression so you learn the logic of that clause. 如果没有,请尝试简化“else”表达式,以便了解该子句的逻辑。 Then I'm sure you'll get it. 然后我相信你会明白的。 You're doing well. 你表现得很好。

There are logical errors in the code above 1/2 evaluates to 0, not to 0.5. 1/2以上的代码中存在逻辑错误,评估为0,而不是0.5。 To do that, either use 0.5 or 1/2.0 or 1.0/2 要做到这一点,要么使用0.5或1 / 2.0或1.0 / 2

Also it does not take care of 2 as a special case. 此外,它不会照顾2作为一个特例。 as (for i in range(3, int(x**(1/2.0))+1, 2) if not (x%i==0)) is not executed as (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) is also a logical error as whenever this condition is true, it causes multiple entries to be added for i in range(3, int(x**(1/2.0))+1, 2) if not (x%i==0)也是一个逻辑错误,因为只要这个条件为真,就会导致多个条目加上

the correct way would be 正确的方法是

[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)]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM