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如果你能把它写进一个答案,我可以接受:)。