Python 获取/搜索集合中元素的引用

Python 获取/搜索集合中元素的引用,python,set,Python,Set,对于一个自定义对象,我有一个自定义的\uuuuueq\uuuuuu和\uuuuuuuuuuu散列函数,它只依赖于一个唯一的“名称”。然后将此类的对象放入一个集合中 现在我想在集合中搜索/查找一个元素: class Resource: def __init__(self, name, rest) self.name = name # .... def __hash__(self): return hash(self.name)

对于一个自定义对象,我有一个自定义的
\uuuuueq\uuuuuu
\uuuuuuuuuuu散列
函数,它只依赖于一个唯一的“名称”。然后将此类的对象放入一个集合中

现在我想在集合中搜索/查找一个元素:

class Resource:
    def __init__(self, name, rest)
        self.name = name
        # ....

    def __hash__(self):
        return hash(self.name)

    def __eq__(self, other):
        return self.name == other.name

s = {Resource("test", 10), Resource("test2", 20)}
然后如何搜索具有“相等”的对象:
test
?作为最后的手段,我可以使用字典,但那将是相当丑陋的,因为“钥匙”将被存储在两个地方,这可能会导致困难的错误



只是澄清一下:我不是在寻找“in”,我是在寻找一种返回参考的方法。

集合基本上是容器,通常用于收集独特的项目。它们没有顺序,单个元素也无法直接访问。因此,从集合中获取元素是不可能的

一种可能的解决方案是使用集合交集操作,如下所示

{Resource("test", 30)} & s
结果将再次设置
。因此,您可能希望将其转换为列表或元组,然后从中访问元素。比如说,

common = {Resource("test", 30)} & s
if common:
    result = tuple(common)[0]
即使现在,
result
也不必是
集合中的对象。从
集合
的角度来看,
资源(“test”,30)
资源(“test”,10)
是一个相同的集合,因为它们根据比较逻辑是相等的。因此,它可以选择返回其中任何一个。不能保证您将从
集合
中获得相应的对象



PS:对于这个用例,我建议使用字典,正如你在问题本身中提到的。

我同意@thefourtheye;对于您展示的示例类,
dict
可能是更好的选择。如果您的用例确实需要一个
集合
,那么您可以创建一个特殊的类,它是
dict
集合
的交叉:

import collections

class MySuperSpecialSet(dict, collections.MutableSet):
    def __init__(self, it=[]):
        for v in it:
            self.add(v)

    def add(self, v):
        super(MySuperSpecialSet, self).__setitem__(v, v)

    def discard(self, v):
        try:
            super(MySuperSpecialSet, self).__delitem__(v)
        except Exception:
            pass

    # make sure some `dict` methods are hard to call by accident
    __setitem__ = None
    keys = iterkeys = viewkeys = None
    items = iteritems = viewitems = None
    values = itervalues = viewvalues = None
    copy = None
    fromkeys = None
    popitem = None

    # some MutableSet methods that should override dict methods
    pop = collections.MutableSet.pop
    update = collections.MutableSet.__ior__


s = MySuperSpecialSet([Resource("test", 10), Resource("test2", 20)])

test2 = Resource("test2", 2)
test2_orig = s[test2]

test2.rest == test2_orig.rest  # False
为了提高效率,您需要手动实现
集合.MutableSet
中的一些方法,但是这个基本类可以完成内置
集合
所能做的几乎所有事情,以及
dict
所能做的一些事情(如
\uuuu getitem\uuuuu
,这是您所要求的行为所需要的)

我还建议您使您的散列更独特一点,这样您就不会与字符串发生散列冲突

class Resource(object):
    def __init__(self, name, rest)
        self.name = name
        # ....

    def _key(self):
        return (type(self), self.name)

    def __hash__(self):
        return hash(self._key())

    def __eq__(self, other):
        try:
            return self._key() == other._key()
        except AttributeError:
            return False

你的意思是什么?试试s中的
Resource(“test”,“dummy”),它会返回
True
@thefourtheye,而不是测试一个项目是否“在”集合中,我希望返回一个引用-这样我就可以检查/修改它的其他变量(以及执行任何其他操作)。你无法从
集合中获取项目
(即使使用类似于
tuple({Resource(“test”,30)}&s)[0]
,也不能保证获得集合中的实际项,因为从
set
的角度来看,如果两个对象相等,那么它们是一个相同的对象。因此,它可能返回检查中使用的对象).我建议使用字典法。@thefourtheye如果你能把它写进一个答案,我可以接受:)。