【问题标题】:Python - What's the difference between "in" and "in x for x in"Python - “in”和“in x for x in”有什么区别
【发布时间】:2014-02-28 01:12:03
【问题描述】:

这是我的 Python 代码:

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

# 2)
if (x not in y):

其中 y 可以是如下列表:

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

谁能解释一下这两个句子的区别? 谢谢!

【问题讨论】:

    标签: python data-structures containers generator membership


    【解决方案1】:

    发电机

    首先,(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 必须是可迭代的,以便测试包含哪些字符串,但在这种情况下,您只会看到长度为 1 的字符串中是否存在某些内容。一个更好的例子是使用整数:

    y = [1, 2, 3]
    

    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 是什么?
    • @Krishath 它会检查 x 是否是这些单词中的一个字母。例如,x = 'h' > Truex = 'p' > False; x = 'hello' > False
    【解决方案2】:

    让我们先从简单的开始:

    if (x not in y):
    

    括号在那里没有任何意义,所以这等价于:

    if x not in y:
    

    in operator 检查某些东西是否包含在其他东西中。在您的情况下,您有一个列表y,因此您正在检查列表y 中是否不包含 (not in) 的内容(x)。所以'1' not in y 将是False,因为'1'y 的一个元素,而'4' not in y 将是True,因为'4' 不是y 的一个元素。

    另一个是完全不同的东西:

    if (x not in z for z in y)
    

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

    for z in y:
        yield x
    

    您之前可能听说过list comprehensions;这些是相似的,但使用方括号而不是括号:[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,这将导致一个包含三个布尔值的列表。现在一个非空列表总是正确的,所以不管这个检查的结果如何,if-check 都会成功。

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

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

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

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

    【讨论】:

      【解决方案3】:
      1. 这个

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

        等价于

        if True:
        

        因为

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

        if (x not in y):
        

        是一样的

        if x not in y:
        

        内部解析为

        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):
      

      【讨论】:

        【解决方案4】:

        我假设这是一个普遍问题,列表中的实际值并不重要。

        为:

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

        语句中的for 表示您有一个“列表理解”或“生成器表达式”(在括号内)。它将生成一个列表。这是一个带有过滤器的列表理解(x not in z 部分)。但最终结果将是一个可能为空也可能不是空的列表。现在if 语句将评估它的“真实性”,其中空列表被认为是错误的,非空列表是真实的。

        2) if (x not in y):
        

        这是一个直接的“包含测试”,直接测试 x 是否包含(或不包含)在可迭代的 y 中,并返回一个布尔值。这可能是一个快速测试,具体取决于 y 是什么类型的对象。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-10-12
          • 1970-01-01
          • 1970-01-01
          • 2018-03-16
          • 1970-01-01
          • 2016-12-16
          • 1970-01-01
          相关资源
          最近更新 更多