什么是更符合Python风格的“not”方式?

35

我两种方式都见过,但哪种方式更符合 Python 风格?

a = [1, 2, 3]

# version 1
if not 4 in a:
    print 'is the not more pythonic?'

# version 2
if 4 not in a:
    print 'this haz more engrish'

哪种方式被认为是更好的Python?


6
第二个,我敢打赌。 - StoryTeller - Unslander Monica
7
第二个句子在英语中读起来很顺畅,而且与预期的效果一样,可以采用。 - mnagel
1
严肃地说,这些答案中很多并不是基于主观意见。似乎有许多编程相关的理由可以优先选择其中之一,并且两者都得到了表扬。答案中展示了参考资料和具体专业知识。 - Derek Litz
4个回答

48

第二个选项更符合Python语言的风格,有两个原因:

  • 这是一个运算符,翻译成一个字节码操作数。而另一行代码实际上是not (4 in a),需要两个运算符。

    恰好地,Python优化了后者的情况,并将not (x in y)翻译成x not in y,但这是CPython编译器的具体实现细节。

  • 这更接近于在英语中使用相同逻辑的方式。

6
你能引用一下这个来源吗? - ThePrimeagen
1
@AshwiniChaudhary:这是由编译器进行的CPython优化。 - Martijn Pieters
3
@MartijnPieters 找到了,链接在这里 http://hg.python.org/cpython/file/ed8b0ee1c531/Python/peephole.c#l405 ;) - Ashwini Chaudhary
1
@AshwiniChaudhary:没错。我所说的就是窥孔优化。 - Martijn Pieters
2
这仍然是一种观点,幸运的是,没有人被迫遵守它。 - michaelmeyer
2
@doukremt 事实上,存在引用,Pythonic 是可以理解的概念,也有特定的专业知识。我觉得有点讽刺的是,那些不理解这些东西的人可以基于他们的看法而关闭某些东西,认为这是一种观点。第二个确实是更符合 Python 语言风格的使用方法。让我简单地说,[bar for bar in baz if not not not not not '0' not in str(bar)] 不太符合 Pythonic 风格,而 [bar for bar in baz if not not not not not '0' not in str(bar)] 则符合 Pythonic 风格。 - Derek Litz

22

大多数人都会同意4 not in a更符合Pythonic。

Python的设计目的是易于理解和可读性强,4 not in a听起来更像你用英语说的方式——很有可能你不需要了解Python就可以理解这个意思!

请注意,在字节码方面,两者在CPython中将是相同的(尽管not in在技术上是单个运算符,但not 4 in a是可以进行优化的):

>>> import dis
>>> def test1(a, n):
        not n in a


>>> def test2(a, n):
        n not in a


>>> dis.dis(test1)
  2           0 LOAD_FAST                1 (n)
              3 LOAD_FAST                0 (a)
              6 COMPARE_OP               7 (not in)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        
>>> dis.dis(test2)
  2           0 LOAD_FAST                1 (n)
              3 LOAD_FAST                0 (a)
              6 COMPARE_OP               7 (not in)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        

这是因为CPython编译器使用窥孔优化来解决这个问题,但这并不意味着IronPython和Jython也会这样做。 - Martijn Pieters
@MartijnPieters 好的,我记下了。你确定其他实现是否有或没有(我假设它们有)? - arshajii
我知道窥视孔优化不是语言规范的一部分,因此其他实现完全可以添加或忽略它们。 - Martijn Pieters
我无法在Jython编译器中找到任何相同优化的代码。 - Martijn Pieters
指出“not in”是自己的运算符是一个好的观点。 - edaniels

8

我认为 not in 更常用。

虽然 PEP 8 风格指南没有明确讨论此主题,但它认为 not in自己的比较运算符

别忘了 Python之禅。 Python 编写的核心原则之一是“可读性至上”,因此在代码中选择最清晰易懂的选项。


2
尽管在独立选择时,4 not in a更为理想,但有时可以优先选择另一个选项not 4 in a
例如,如果软件规范是按照not 4 in a编写的,则最好保持与规范匹配,以便在检查软件是否符合规范时提供帮助。
另一个例子是,一种方式允许表达健康状况恶化的情况:
( 4 in well,
  well,
  not well,
  not 4 in well) #!

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