Python - "in"和"in x for x in"之间的区别是什么

pep*_*nas 5 python membership containers generator data-structures

这是我的Python代码:

# 1)
if (x not in z for z in y):

# 2)
if (x not in y):
Run Code Online (Sandbox Code Playgroud)

其中y可以是如下列表:

y = ['1','2','3']
Run Code Online (Sandbox Code Playgroud)

有人能解释一下这两句话的区别吗?谢谢!

Aar*_*all 6

发电机

首先,(x not in z for z in y)是一个生成器语句,如果if在它前面,它将始终返回True.

if (x not in z for z in y): # Always returns True
Run Code Online (Sandbox Code Playgroud)

这可以用于查看是否包含任何或所有嵌套的iterables x.

例如

if any(x in z for z in y): # Returns True if any of the z's contain x
if all(x in z for z in y): # Returns True only if all of the z's contain x
Run Code Online (Sandbox Code Playgroud)

所以如果y是这样的话:

y = ['hello','how','are','you']
Run Code Online (Sandbox Code Playgroud)

然后,如果x是,例如,'e'那么any上面的理解将返回True,但all理解将返回False.

条件

所以这就是生成器理解中发生的事情:如果y是一个列表,那么你测试:

(x not in z for z in y)
Run Code Online (Sandbox Code Playgroud)

y中的z必须是可迭代的,以便测试包含,哪些字符串是,但是你只是看到在这种情况下某些东西是长度为1的字符串.一个更好的例子是使用整数:

y = [1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

if (x not in z for z in y):
Run Code Online (Sandbox Code Playgroud)

会失败,因为整数不可迭代,但是

if (x not in y):
Run Code Online (Sandbox Code Playgroud)

会成功,因为你可以测试实际列表中的成员资格.

当你有

y = ['1','2','3']
Run Code Online (Sandbox Code Playgroud)

类似的嵌套级别是:

y = [(1,), (2,), (3,)]
Run Code Online (Sandbox Code Playgroud)

(x not in z for z in y)
Run Code Online (Sandbox Code Playgroud)

你正在测试x是否在其中一个元组中.

那有意义吗?


pok*_*oke 4

让\xe2\x80\x99s 首先从简单的开始:

\n\n
if (x not in y):\n
Run Code Online (Sandbox Code Playgroud)\n\n

括号 don\xe2\x80\x99t 在那里具有任何含义,因此这相当于:

\n\n
if x not in y:\n
Run Code Online (Sandbox Code Playgroud)\n\n

操作in检查某些内容是否包含在其他内容中。就您而言,您有一个列表y,因此您要检查该列表( x)中是否不包含某些内容( ) 。所以会是因为是 的元素,并且会是因为不是 的元素。not iny\'1\' not in yFalse\'1\'y\'4\' not in yTrue\'4\'y

\n\n

另一种则完全不同:

\n\n
if (x not in z for z in y)\n
Run Code Online (Sandbox Code Playgroud)\n\n

这里我们有一个生成器表达式。生成器表达式的格式(x for z in y)与此代码等效:

\n\n
for z in y:\n    yield x\n
Run Code Online (Sandbox Code Playgroud)\n\n

您以前可能听说过列表推导式;它们很相似,但使用方括号而不是圆括号:[x for z in y]。当他们返回一个列表时,他们更容易理解。它们等价于:

\n\n
lst = []\nfor z in y:\n    lst.append(x)\nreturn lst\n
Run Code Online (Sandbox Code Playgroud)\n\n

本质上,您正在循环 的元素y,在迭代中调用每个元素\nz并返回x该元素。在您的情况下,x是一个表达式本身:x not in z与上面基本相同:您正在检查是否x包含在 中 z

\n\n

现在,生成器表达式有点复杂,因为它们是在请求元素时计算的,所以让\xe2\x80\x99s 现在假设我们有一个列表理解

\n\n
if [x not in z for z in y]:\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以它的作用是计算中的x not in z每个元素。因此,对于您的,结果列表将是这样的:zyy

\n\n
[x not in \'1\', x not in \'2\', x not in \'3\']\n
Run Code Online (Sandbox Code Playgroud)\n\n

对于 real x,这将产生一个包含三个布尔值的列表。现在非空列表总是 trueish,因此无论此检查的结果如何,-checkif都会成功。

\n\n

不过,生成器表达式将返回一个生成器,它是一个比列表更复杂的对象。不过,这也是真实的,因此无论各个值如何,您的检查也会成功。

\n\n

现在想象一下,我们想要确保,对于列表中的这三个元素,我们希望所有检查的结果都是True。为此,我们可以使用all()本质上检查列表\xe2\x80\x94 或生成器\xe2\x80\x94 中的值是否仅包含真值的函数。

\n\n
if all(x not in z for z in y):\n
Run Code Online (Sandbox Code Playgroud)\n\n

x因此,如果不包含在列表的任何元素中,则这将成功y。另一方面,如果我们想检查列表或生成器中是否至少有一个真实值,那么我们可以使用该any()函数。

\n