python 运算符,“not in”没有运算符

Posted

技术标签:

【中文标题】python 运算符,“not in”没有运算符【英文标题】:python operator, no operator for "not in" 【发布时间】:2012-07-11 05:19:18 【问题描述】:

这可能是一个愚蠢的问题,但是查看the mapping of operators to functions 我注意到没有表达not in 运算符的函数。起初我认为这可能是因为解释器只是将其重新排序为not x in y,但is not 有一个函数,它的行为似乎与not in 完全相同。是我遗漏了什么,还是该运算符真的不存在?

这是一个非常愚蠢的例子,你可能想要这个:

def compare_iter(a,b,func):
    return [func(aa,bb) for aa,bb in zip(a,b)]

my_compare=compare_iter(xx,yy,lambda x,y:x not in y)  #lambda -- yuck
my_compare=map(operator.not_,compare_iter(xx,yy,operator.contains)  #extra map?  grr...
#it would be nice to do: my_compare=compare_iter(xx,yy,operator.not_contains)

当然,我可以为此编写自己的函数,但是你会付出效率的代价,而操作员模块可以将这段代码从 python 中推出,因此执行得更快。

【问题讨论】:

确实,不能将a is not b 简单地重新排序为not a is b 吗? 是否存在检查not in 可能比检查in 更快的情况? @PaulManta 值得怀疑,因为not in 根据定义是一个详尽的搜索。 @JAB -- 可以。但这不是重点。关键是这里有一个不对称,这有点好笑。似乎应该有一个not_contains 函数,然后可以用来传递给其他函数或其他任何东西(而不是依赖lambda)。 @ColinDunklau 不一定。想想像布隆过滤器这样的事情,如果没有设置一个位,您可以确定该项目没有插入到集合中。 【参考方案1】:

这里不需要其他功能。 not inin 的倒数,所以你有以下映射:

obj in seq => contains(seq, obj)

obj not in seq => not contains(seq, obj)

你说得对,这与is/is not 不一致,因为身份测试应该是对称的。这可能是一个设计工件。

【讨论】:

考虑到这一点,在我看来,另一个运算符应该是必要的。 x > y 并不(必然)在 python 中暗示 not (x <= y)。为什么收容测试应该有所不同?【参考方案2】:

您可能会发现以下函数和反汇编有助于理解运算符:

>>> def test():
        if 0 in (): pass
        if 0 not in (): pass
        if 0 is (): pass
        if 0 is not (): pass
        return None

>>> dis.dis(test)
  2           0 LOAD_CONST               1 (0) 
              3 LOAD_CONST               2 (()) 
              6 COMPARE_OP               6 (in) 
              9 POP_JUMP_IF_FALSE       15 
             12 JUMP_FORWARD             0 (to 15) 

  3     >>   15 LOAD_CONST               1 (0) 
             18 LOAD_CONST               3 (()) 
             21 COMPARE_OP               7 (not in) 
             24 POP_JUMP_IF_FALSE       30 
             27 JUMP_FORWARD             0 (to 30) 

  4     >>   30 LOAD_CONST               1 (0) 
             33 LOAD_CONST               4 (()) 
             36 COMPARE_OP               8 (is) 
             39 POP_JUMP_IF_FALSE       45 
             42 JUMP_FORWARD             0 (to 45) 

  5     >>   45 LOAD_CONST               1 (0) 
             48 LOAD_CONST               5 (()) 
             51 COMPARE_OP               9 (is not) 
             54 POP_JUMP_IF_FALSE       60 
             57 JUMP_FORWARD             0 (to 60) 

  6     >>   60 LOAD_CONST               0 (None) 
             63 RETURN_VALUE         
>>> 

如您所见,每个运算符都有所不同;它们的代码(按顺序)是 6、7、8 和 9。

【讨论】:

是的,但是如果你做not 0 in (),它就会把它翻译成0 not in ()——这让我更加想在操作符模块中应该有一个对应的操作符,因为not in显然是解释器的独特(甚至是首选)运算符... @mgilson:我自己也注意到了。我想它会是相反的方式,但现在我发现自己同意你的观点。有趣的是,我似乎找不到任何关于将not in 作为operator 的成员包含在Python 官方邮件列表中的讨论,尽管有人讨论了它的用处。 @JAB,您能否发布一些关于有用性的讨论的链接? (这个问题对我来说主要是学术性的,我很想看看其他人对实际用例的看法)有没有办法要求添加它? 我想为not in 使用单个字节码比先计算in 然后再计算not 更有效。

以上是关于python 运算符,“not in”没有运算符的主要内容,如果未能解决你的问题,请参考以下文章

NOT IN 运算符问题 Oracle

JavaScript 中是不是有用于检查对象属性的“not in”运算符?

Oracle In(匹配)子句

Oracle In(匹配)子句

MySQL学习15:子查询

好程序员分享Python自动化运维开发实战五-运算符与表达式