【问题标题】:Python's "in" set operatorPython 的“in”集合运算符
【发布时间】:2021-07-22 17:42:41
【问题描述】:

我对用于集合的 python in 运算符有点困惑。

如果我有一个集合s 和一些实例b,那么b in s 是否真的意味着“s 中是否有一些元素x 使得b == xtrue ”?

【问题讨论】:

  • 计算机科学家。我只是有点困惑,因为文档说“测试 x 以获取 s 中的成员资格”。对我来说,这可能意味着“实例 x 包含在 s 中”或“s 中存在与 x 具有相同值的某个实例”。我不知道这是身份比较还是平等比较。
  • @Dejas:既然您知道 Python 有两个运算符相等比较和恒等比较,您应该能够构建一个实验来确认每个运算符。如果您发布该实验会有所帮助。

标签: python


【解决方案1】:

是的,但它表示hash(b) == hash(x),因此项目的相等性不足以使它们相同。

【讨论】:

  • 好的,“s 中是否有元素 x 使得 hash(b) == hash(x) 和 x == b”?
  • 如果有人以扭曲的方式实现了他的类的哈希函数,这就是他可能得到(并且应得的)。
  • 我认为membership testing 上的文档应该更清楚地说明哈希相等是setfrozensetdict 的先决条件。 2015 年的错误报告中讨论了类似的改进,但不幸的是它在 2019 年关闭:bugs.python.org/issue23987#msg241661
【解决方案2】:

没错。您可以像这样在解释器中尝试:

>>> a_set = set(['a', 'b', 'c'])

>>> 'a' in a_set
True

>>>'d' in a_set
False

【讨论】:

  • 这不是一个很好的测试,因为字符串常量经常被保留(试试a = 'a'; b = 'a'; a is b)。我用a = (1, 2, 3); b = (1, 2, 3); a == b; hash(a) == hash(b); a is b; a in set([b]) 代替了它。
【解决方案3】:

是的,它可以是这个意思,也可以是一个简单的迭代器。例如: 作为迭代器的示例:

a=set(['1','2','3'])
for x in a:
 print ('This set contains the value ' + x)

类似于支票:

a=set('ILovePython')
if 'I' in a:
 print ('There is an "I" in here')

已编辑:已编辑以包含集合而不是列表和字符串

【讨论】:

  • 这和集合有什么关系?
  • 好吧,我想一个列表甚至一个字符串都可以被认为具有与集合相似的属性。它们是元素的集合。
  • 不,集合有一个额外的条件来进行包含检查,而序列没有。
【解决方案4】:

Sets 的行为与 dicts 不同,您需要使用 set 操作,例如 issubset():

>>> k
{'ip': '123.123.123.123', 'pw': 'test1234', 'port': 1234, 'debug': True}
>>> set('ip,port,pw'.split(',')).issubset(set(k.keys()))
True
>>> set('ip,port,pw'.split(',')) in set(k.keys())
False

【讨论】:

  • 这很有趣。还有一个很棒的真实应用程序。
  • 这正是把我带到这里的令人惊讶的结果。
  • 为什么令人惊讶? in 运算符测试 element 成员资格,并适用于集合、字典、列表、元组等。第二个测试是(天真地)测试 set 是否是键集的 element。不,它不是:键集只包含键,而不是集合
【解决方案5】:

字符串虽然不是set 类型,但在脚本验证期间具有有价值的in 属性:

yn = input("Are you sure you want to do this? ")
if yn in "yes":
    #accepts 'y' OR 'e' OR 's' OR 'ye' OR 'es' OR 'yes'
    return True
return False

我希望这可以帮助您更好地理解 in 在此示例中的用法。

【讨论】:

  • 那不是一套。字符串也不可变。
  • ... or 'e' or 'es' or 's'。考虑删除这个毫无意义的错误答案。
【解决方案6】:

List 的 __contains__ 方法使用其元素的 __eq__ 方法。而 set 的 __contains__ 使用 __hash__。看一下我希望明确的以下示例:

class Salary:
    """An employee receives one salary for each job he has."""

    def __init__(self, value, job, employee):
        self.value = value
        self.job = job
        self.employee = employee

    def __repr__(self):
        return f"{self.employee} works as {self.job} and earns {self.value}"

    def __eq__(self, other):
        """A salary is equal to another if value is equal."""
        return self.value == other.value

    def __hash__(self):
        """A salary can be identified with the couple employee-job."""
        return hash(self.employee) + hash(self.job)

alice = 'Alice'
bob = 'Bob'
engineer = 'engineer'
teacher = 'teacher'

alice_engineer = Salary(10, engineer, alice)
alice_teacher = Salary(8, teacher, alice)
bob_engineer = Salary(10, engineer, bob)

print(alice_engineer == alice_teacher)
print(alice_engineer == bob_engineer, '\n')

print(alice_engineer is alice_engineer)
print(alice_engineer is alice_teacher)
print(alice_engineer is bob_engineer, '\n')

alice_jobs = set([alice_engineer, alice_teacher])
print(alice_jobs)
print(bob_engineer in alice_jobs)  # IMPORTANT
print(bob_engineer in list(alice_jobs))  # IMPORTANT

控制台打印:

False
True 

True
False
False 

{Alice works as teacher and earns 8, Alice works as engineer and earns 10}
False
True

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-11
    • 1970-01-01
    • 1970-01-01
    • 2011-01-14
    • 1970-01-01
    相关资源
    最近更新 更多