【问题标题】:"x not in" vs. "not x in" [duplicate]“x not in”与“not x in”[重复]
【发布时间】:2011-03-29 17:38:53
【问题描述】:

我注意到这两者的工作方式相同:

if x not in listif not x in list

在某些情况下,两者之间有什么区别吗?两者兼而有之是有原因的,还是仅仅是因为某些人写其中一个更自然?

我更有可能在其他人的代码中看到哪一个?

【问题讨论】:

标签: python operators


【解决方案1】:

这只是个人喜好。您还可以比较if x != 3if not x == 3。您显示的两个表达式之间没有区别。

【讨论】:

  • 这些并不相同。 != 调用 __ne__== 调用 __eq__。在反常情况下,您的示例可能会产生不同的结果
  • 确实如此。我应该加上,“除了变态”!
【解决方案2】:

not x in L 没有被明确禁止,因为这很愚蠢。 x not in L 被明确允许(尽管它编译为相同的字节码),因为它更具可读性。

x not in L 是每个人都使用的。

【讨论】:

    【解决方案3】:

    当您编写a not in b 时,它使用not in 运算符,而not a in b 使用in 运算符然后否定结果。但是not in 运算符被定义为返回与not a in b 相同的结果,因此它们的作用完全相同。来自documentation

    运算符innot in 测试集合成员资格。如果x 是集合s 的成员,x in s 的计算结果为 true,否则为 false。 x not in s 返回对 x in s 的否定。

    a is not bnot a is b 类似。

    添加了额外的语法是因为它使人类更容易自然地阅读它。

    【讨论】:

    • 奇怪的是,当您使用dis 模块时,它表明它们都使用not in 进行比较,尽管文档说...
    【解决方案4】:
    >>> dis.dis(lambda: a not in b)
    1           0 LOAD_GLOBAL              0 (a)
              3 LOAD_GLOBAL              1 (b)
              6 COMPARE_OP               7 (not in)
              9 RETURN_VALUE      
    
    >>> dis.dis(lambda: not a in b)
    1           0 LOAD_GLOBAL              0 (a)
              3 LOAD_GLOBAL              1 (b)
              6 COMPARE_OP               7 (not in)
              9 RETURN_VALUE  
    

    当您执行“not a in b”时,需要将其转换为(not in)

    所以,正确的做法是“a not in b”。

    【讨论】:

      【解决方案5】:

      这两种形式的字节码完全相同,您可以清楚地验证:

      >>> import dis
      >>> dis.dis(compile('if x not in d: pass', '', 'exec'))
        1           0 LOAD_NAME                0 (x)
                    3 LOAD_NAME                1 (d)
                    6 COMPARE_OP               7 (not in)
                    9 JUMP_IF_FALSE            4 (to 16)
                   12 POP_TOP             
                   13 JUMP_FORWARD             1 (to 17)
              >>   16 POP_TOP             
              >>   17 LOAD_CONST               0 (None)
                   20 RETURN_VALUE        
      >>> dis.dis(compile('if not x in d: pass', '', 'exec'))
        1           0 LOAD_NAME                0 (x)
                    3 LOAD_NAME                1 (d)
                    6 COMPARE_OP               7 (not in)
                    9 JUMP_IF_FALSE            4 (to 16)
                   12 POP_TOP             
                   13 JUMP_FORWARD             1 (to 17)
              >>   16 POP_TOP             
              >>   17 LOAD_CONST               0 (None)
                   20 RETURN_VALUE        
      

      显然它们在语义上是相同的。

      就风格而言,PEP 8 没有提及该问题。

      就我个人而言,我更喜欢if x not in y 形式——这清楚地表明not in 是一个单一的运算符,并且“读起来像英语”。 if not x in y 可能会误导一些读者认为它的意思是if (not x) in y,读起来有点不像英文,而且绝对没有任何补偿优势。

      【讨论】:

      • PEP 8 提到了类似的偏好:“使用is not 运算符而不是not ... is。虽然这两种表达方式在功能上是相同的,但前者更具可读性和更受欢迎。”
      猜你喜欢
      • 2019-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-30
      • 2021-11-03
      相关资源
      最近更新 更多