如何使用等效对象访问集合的元素?

时间:2011-12-23 12:48:07

标签: python set object-identity

如果我有一个比较等于Python集元素的对象,但不是同一个对象,是否有合理的方法来获取对集合中对象的引用?用例将使用该集来识别和共享重复数据。

示例(Python 2.7):

>>> a = "This is a string"
>>> b = "This is a string"
>>> a is b
False
>>> a == b
True
>>> s = set((a,))
>>> b in s
True

如何使用ab来引用s?我可以想到一种方法,但是我不确定它是否与实现无关:是a还是b编辑:当s有多个元素时,这不起作用;交集很自然地实现了像[x for x in smaller_set if x in larger_set]

这样的东西
>>> for x in set((b,)).intersection(s): c = x
...
>>> c is a
True

也许一个好的解决方法是使用将每个键映射到自身的字典而不是集合。

2 个答案:

答案 0 :(得分:5)

我在python-list上发现了一个类似的问题:Get item from set。参考get_equivalent(container, item) (Python recipe)有一个聪明的答案。

诀窍是为'key'对象构造一个包装器对象,并使用in运算符检查包装器是否在集合中。如果包装器哈希值等于键,则其__eq__方法可以访问集合中的对象,并保存对它的引用。讨论的一个重点是,对于无法识别的类型,set元素的__eq__方法必须返回NotImplemented,否则可能无法调用包装器的__eq__

答案 1 :(得分:1)

您的用例听起来像是词典的用例。使用比较等于“外部”对象的对象的属性作为键,并将所需对象本身作为值。

如果它是一个简单的用例,并且你可以有一个线性的seartch,但是,你可以做到这一点 - 这不会是坏事:

def get_equal(in_set, in_element):
   for element in in_set:
       if element == in_element:
           return element
   return None 

如果你需要你究竟要求的东西(我可以想到一些用例) - wya去创建一个自定义字典类,其中有一个集合作为其成员之一,实现代理mehthods到成员集,以及字典和集合方法,保持字典和设置内容的同步。实现这一点非常耗时,但相对简单。