Python - "in"和"in x for x in"有什么区别?

5
这是我的Python代码:
# 1)
if (x not in z for z in y):

# 2)
if (x not in y):

其中y可能是一个列表,例如:

y = ['1','2','3']

有人能解释一下这两个句子之间的区别吗? 谢谢!

4个回答

6

生成器

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

if (x not in z for z in y): # Always returns True

这可以用来查看任何或所有嵌套的可迭代对象是否包含 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

如果y是这样的:

y = ['hello','how','are','you']

那么,如果x'e',则上面的any推导式将返回True,但all推导式将返回False

条件语句

因此,在生成器推导式中发生了什么:如果y是一个列表,并且您进行测试:

(x not in z for z in y)

在测试包含性时,y 中的 z 必须是可迭代的。字符串可以作为可迭代对象,但在这种情况下,您只能查看长度为一的字符串中是否存在某些内容。更好的例子是使用整数:
y = [1, 2, 3]

and

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

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

if (x not in y):

如果你能测试实际列表中的成员资格,那么将成功。

当你拥有

y = ['1','2','3']

一个类似的嵌套层次将会是:
y = [(1,), (2,), (3,)]

并且使用

(x not in z for z in y)

你正在测试x是否在其中一个元组中。
这样说清楚了吗?

非常感谢!如果 y = ['hello','how','are','you'] 呢?那么 x 是什么? - peperunas
@Krishath 它会检查x是否为这些单词中的任意一个字母。例如,x = 'h' > True; x = 'p' > False; x = 'hello' > False - Samie Bencherif

4

首先从简单的开始:

if (x not in y):

这里的括号没有任何含义,因此这等同于:

if x not in y:
str.replace() 方法用于将一个字符串中的一些文本替换为另一些文本。在这个方法中,你需要指定要被替换的原始文本(例如 'world')和新的文本(例如 'Python'),并将它们作为字符串参数传递给该方法。例如,如果你有一个字符串 x = "Hello, world!",那么 x.replace('world', 'Python') 将返回一个新的字符串 "Hello, Python!",其中所有出现的 'world' 都被替换为 'Python'。注意,这个方法不会改变原始字符串,而是返回一个新的替换后的字符串。
if (x not in z for z in y)

这里我们有一个生成器表达式。生成器表达式的格式为(x for z in y),等同于以下代码:

for z in y:
    yield x

你可能听说过 列表解析;它们与生成器表达式类似,但使用方括号而不是圆括号: [x for z in y]。由于它们返回一个列表,因此更容易理解。它们等同于以下内容:

lst = []
for z in y:
    lst.append(x)
return lst

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

现在,生成器表达式有点复杂,因为当请求元素时它们被评估,所以现在假设我们有一个列表推导式。

if [x not in z for z in y]:

这个功能是为每个在列表 y 中的元素 z 计算 x not in z。所以对于你的 y,结果列表将会是这样的:

[x not in '1', x not in '2', x not in '3']

使用真实的 x,这将导致一个包含三个布尔值的列表。现在,非空列表总是会被视为 trueish,因此无论检查结果如何,if 检查都将成功。
生成器表达式将返回一个生成器,它是一个比列表更复杂的对象。它同样也是唯一的 true-ish,因此您的检查也将成功,无论个别值如何。
现在假设我们想确保对于列表中的这三个元素,我们希望所有检查结果均为 True。为此,我们可以使用 all() 函数,它基本上检查列表或生成器中是否仅包含 true 值。
if all(x not in z for z in y):

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


2
  1. This

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

    is equivalent to

    if True:
    

    Because

    >>> (x not in z for z in y)
    <generator object <genexpr> at 0x000000E7AE26FB88>
    >>> bool(_)
    True
    
  2. This

    if (x not in y):
    

    Is the same as

    if x not in y:
    

    Which resolves internally to

    if not y.__contains__(x):
    
在第一种情况下,您可能想要写的是:
if any(x not in z for z in y):
# same as
if not all(x in z for z in y):

或者:

if all(x not in z for z in y):
# same as
if not any(x in z for z in y):

2
我会假设这是一个普遍性问题,实际列表中的值并不重要。
对于:
1) if (x not in z for z in y):
< p > for in语句表示您有一个“列表推导式”或“生成器表达式”(在括号内)。它将生成一个列表。这是一个带有过滤器的列表推导式(x not in z部分)。但最终结果将是一个可能为空的列表。现在,if语句将对其进行“真值”评估,其中空列表被视为false,非空列表则为true。

2) if (x not in y):

这是一个直接的“包含测试”,用于测试可迭代对象y中是否直接包含(或不包含)变量x,并返回一个布尔值。根据y的类型,这可能是一个快速测试。

第一种形式在大多数情况下可能更慢且不必要。第一种形式必须创建然后销毁一个临时列表。


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