我遇到了一个关于Stack Overflow的解决方案,该解决方案使用列表推导生成素数。但是无法理解内部for循环的作用。
我尝试过类似的事情
[x for x in range(5,20) for y in range(2,int(x/2)+1) if any(x%y == 0)]
它引发错误:'bool'对象不可迭代
我知道我的语法是错误的,但是从逻辑上说,对于素数,我们有一个for循环,然后是一个for循环,然后是一个if条件来计算剩余(x%y)。 但是堆栈溢出的答案是
[x for x in range(2, 20) if all(x % y != 0 for y in range(2, x))]
我理解了为什么使用all的原因,但是我无法获得all()内的条件如何按理想方式工作,如果要这样做,则要迭代range(2,x)并且y获得的值是依次用于计算(x%y)。 y在分配值之前如何使用。
答案 0 :(得分:3)
如果列表理解可以像for
循环那样正常工作,那对列表理解来说就是一件很了不起的事情,人们不会创建它,因为for
循环更易读和易懂。
您可能会发现列表理解的结果始终是list
,而for
循环的结果将始终有许多单个值,而这些单个值是iterable
的一部分
[x +1表示范围在(1,5)中的x]
[2,3,4,5]对于范围在(1,10)中的x:print(x + 1)
2
3
4
5
您可以简单地理解循环理解已经具有值列表,然后它们只是简单地按值有序地输入条件值。像这样:
[1 + 1,2 + 1,3 + 1,4 + 1]
您的代码是错误的,因为您从普通的for
循环继承了太多代码。用for循环编写的代码如下:
for x in range(5,20):
for y in range(2,int(x/2)+1):
if any(x%y == 0):
print(x)
结果显然是:
TypeError:“ bool”对象不可迭代
因为any
需要迭代器,例如 @meowgoesthedog 所述的生成器表达式或**list**
。巧合的是,列表仅与列表理解有关。但是,您需要理解它才能很好地利用列表理解。有时候我也会遇到这种情况,在您的情况下,for y in range(2,int(x/2)+1)
就像一个正常的for
循环一样。
在条件if
中,这是可选谓词。我们可以通过遵循以下规则来创建另一个列表理解:x%y==0
是输出表达式,变量y
代表输入序列range(2,int(x/2)+1)
答案 1 :(得分:2)
ALL
和all()
适用于可悲的对象。例如,any()
返回all([True, True, False, True])
。您不能使用False
(例如您的示例:any(True)
)
此语句any(x%y == 0)
可以翻译为以下代码:
[x for x in range(2, 20) if all(x % y != 0 for y in range(2, x))]
Ps。我在注释中看到您不确定res = []
for x in range(2, 20):
temporary_list = (x%y != 0 for y in range(2,x))
if all(temporary_list):
res.append(x)
的声明方式。在python中,除了理解列表以外,还有更多很棒的结构。其中之一是理解力的产生者-我相信在这种情况下会使用它。
答案 2 :(得分:1)
语法all
和any
适用于可迭代对象(列表,集合等)。因此,将其应用于布尔值-x%y==0
时会出错。
您可以通过以下方式使用任何一种-
[x for x in range(5,20) if not any([x % y == 0 for y in range(2, int(x/2)+1)])]
或-
[x for x in range(2, 20) if not any(x % y == 0 for y in range(2, int(x/2)+1))]
彼此互补。