考虑以下代码:
另一种解决方案看起来更有效,但实际上并不起作用:
不是这个:
由于交集的工作方式未定义:
可能是重复问题:
Python:从集合中检索项目
请看下面的代码:
>>> item1 = (1,)
>>> item2 = (2,)
>>> s = set([item1, item2])
>>> s
set([(2,), (1,)])
>>> new_item = (1,)
>>> new_item in s
True
>>> new_item == item1
True
>>> new_item is item1
False
所以new_item
在s
中,因为它等价于其中一个项目,但它是另一个对象。
我想要从s
中得到item1
,已知new_item
在s
中。
我想到的一个解决方案很直接,但不太有效:
def get_item(s, new_item):
for item in s:
if item == new_item:
return item
>>> get_item(s, new_item) is new_item
False
>>> get_item(s, new_item) is item1
True
另一种解决方案看起来更有效,但实际上并不起作用:
def get_item_using_intersection1(s, new_item):
return set([new_item]).intersection(s).pop()
不是这个:
def get_item_using_intersection2(s, new_item):
return s.intersection(set([new_item])).pop()
由于交集的工作方式未定义:
>>> get_item_using_intersection1(s, new_item) is new_item
True
>>> get_item_using_intersection1(s, new_item) is item1
False
>>> get_item_using_intersection2(s, new_item) is new_item
True
>>> get_item_using_intersection2(s, new_item) is item1
False
如果有关系的话,我正在使用Windows 7上的Python 2.7 x64,但我需要一个跨平台的解决方案。
感谢大家,我想出了以下临时解决方案:
class SearchableSet(set):
def find(self, item):
for e in self:
if e == item:
return e
这将来会被以下解决方案所取代(目前非常不完整):
class SearchableSet(object):
def __init__(self, iterable=None):
self.__data = {}
if iterable is not None:
for e in iterable:
self.__data[e] = e
def __iter__(self):
return iter(self.__data)
def __len__(self):
return len(self.__data)
def __sub__(self, other):
return SearchableSet(set(self).__sub__(set(other)))
def add(self, item):
if not item in self:
self.__data[item] = item
def find(self, item):
return self.__data.get(item)
new_item
,如果它与item1
等效呢?(在这种情况下应该是这样的。)如果实际上这些项并不等价,则存在设计问题:您不应将这些对象存储在集合中,就好像它们是一样的。(从你提供的一般性问题描述中很难判断。) - millimoose__hash__
和__eq__
方法,并且两个相等的实例不可互换,那么我认为这是一个设计缺陷。在非“值对象”中实现这些方法并不是一个好主意。 - millimoosepop()
返回new_item
,因为您的临时集合只有1个元素,而s
有2个。您应该像其他人建议的那样使用dict
。 - yak