【问题标题】:How can i combine in and is? [duplicate]我怎样才能结合和是? [复制]
【发布时间】:2021-09-03 12:26:35
【问题描述】:

我有一个对象a 和一个列表,我想检查对象a 是否在该列表中。这意味着具有相同 id 的相同对象。要比较a 和该列表中的单个项目,我会使用is 关键字,类似于a is ls[0],而不是==,因为== 会比较两者的值,而不是它们是否是同一个对象.我知道 in 关键字来查看列表是否包含值但比较值(类似于 ==)而不是对象。

考虑以下代码:

class Foo(object):
  def __init__(self,value):
    self.value=value
  def __eq__(self,other):
    return True

a=Foo(0)
b=Foo(1)
if a is b:
  print("Error, a is b")
  exit()

ls=[b]
if b is not ls[0]:
  print("Error, b is not ls[0]")
  exit()

if a in ls:
  print("Don't print this line")
else:
  print("Print this line instead")

如何更改if 语句以便打印"Print this line instead"

将其更改为 if a is in ls:if a in is ls: 会出现语法错误。是的,我知道我可以制作这样的功能:

def isIn(object,ls):
  for e in ls:
    if e is object:
      return True
  return False

但这看起来很笨拙,有没有更好的方法?

【问题讨论】:

  • 你可以试试id(a) in map(id, ls)
  • any(a is b for b in ls)
  • @Epsi95 很好的答案,为什么将它们放在评论中而不创建答案?
  • @deceze 很好的答案,你为什么将它们放在评论中而不创建答案?
  • 因为已经有很多关于这个的现有答案,比如这个已经被关闭的副本......作为......作为......的副本......无论如何,你知道我的意思。

标签: python


【解决方案1】:

CPython 和 PyPy 已经作为捷径做到了这一点;即在比较相等性时,他们首先检查身份。您可以使用以下代码对其进行测试:

class Test:
    def __init__(self, name): self.name = name
    def __eq__(self, other): print(self, other); return False
    def __str__(self): return self.name


x = [Test(c) for c in 'abcdef']
print(x[2] in x)

输出显示没有c c 相等比较但是in 检查返回True

a c
b c
True

【讨论】:

  • 谢谢,但这不是问题。
  • @12431234123412341234123 那么真正的问题是,你为什么要这么做?
  • 我有一个元素列表,我想检查其中是否有 None== 不应该用于检查None,因为可能存在误报,最好使用is
  • @12431234123412341234123 能解释一下什么情况下会出现误报吗?我看到了你的 Foo 示例类,但它对 __eq__ 的实现是荒谬的,所以你能提供一个真实世界的例子吗?似乎(a)您的数据模型不将None视为特殊/哨兵值,在这种情况下,您不应该首先将Nones放入您的列表中,而是创建一个单独的sentinel = object(),或(b)您的数据模型以其他方式损坏,例如通过这样的Foo.__eq__ 实现。这一切都像XY problem
猜你喜欢
  • 1970-01-01
  • 2022-09-24
  • 2018-07-09
  • 2016-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-24
  • 2021-09-23
相关资源
最近更新 更多