检查对象是否在列表中(不是"按值",而是由id)

Jas*_*per 3 python comparison-operators

请考虑以下代码:

>>> class A(object):
...   def __init__(self, a):
...     self.a = a
...   def __eq__(self, other):
...     return self.a==other.a
... 
>>> a=A(1)
>>> b=A(1)
>>> c=A(2)

>>> a==b
True                   # because __eq__ says so
>>> a==c
False                  # because __eq__ says so
>>> a is b
False                  # because they're different objects

>>> l = [b,c]
>>> a in l
True                   # seems to use __eq__ under the hood
Run Code Online (Sandbox Code Playgroud)

因此,in似乎用于__eq__确定某个容器中是否有东西.

  1. 哪里可以找到有关此行为的文档?
  2. 是否有可能in使用对象标识,即a in somelist对象a是否在somelist,而不是其他一些比较等于的对象a

Mar*_*ers 6

使用any()函数和生成器表达式:

any(o is a for o in l)
Run Code Online (Sandbox Code Playgroud)

" 公共序列运算符"部分中in记录了行为:

x in s
True如果s 的项等于 x,否则False

大胆强调我的.

如果必须使用in,请使用包装器对象和自定义__eq__方法,该方法使用is或构建自己的容器,自定义__contains__方法用于is测试每个包含的元素.

包装器可能如下所示:

class IdentityWrapper(object):
    def __init__(self, ob):
        self.ob = ob
    def __eq__(self, other):
        return other is self.ob
Run Code Online (Sandbox Code Playgroud)

演示:

>>> IdentityWrapper(a) in l
False
>>> IdentityWrapper(a) in (l + [a])
True
Run Code Online (Sandbox Code Playgroud)

容器可以使用any()上面概述的相同功能:

class IdentityList(list):
    def __contains__(self, other):
        return any(o is other for o in self)
Run Code Online (Sandbox Code Playgroud)

演示:

>>> il = IdentityList(l)
>>> a in il
False
>>> a in IdentityList(l + [a])
True
Run Code Online (Sandbox Code Playgroud)