2012-06-17 50 views
6

假设我有一组自定义对象myset,虽然它们的引用不同(a == b and a is not b),但它们可能相等。现在,如果我设置了add(a),那么即使集合中只有len(myset) == 1对象,Python也会正确地假定为a in myset and b in mysetPython:访问集合的成员

这很明显。但是现在是否可以使用b来从集合中提取a的值?假设对象是可变的,我想改变它们,忘记了直接引用a。换言之,我正在寻找myset[b]操作,该操作将返回该集合的成员a

在我看来,类型set不能做到这一点(比迭代所有成员更快)。如果是这样,是否至少有一个有效的解决方法?

+0

为什么你需要做到这一点?如果你已经有'b',为什么你需要'a',这是平等的? –

+0

这是一个富有挑战性的要求... –

+0

@KarlKnechtel:集合中的元素是从其他地方引用的(从深层结构中),我想改变它的值。对象基本上是2D矢量类型,并且它们是可变的。 – emu

回答

5

我不认为set支持检索O(1)时间的项目,但您可以使用dict来代替。

d = {} 
d[a] = a 
retrieved_a = d[b] 
+0

事实上,我已经习惯了这一点,并在前一段时间看了解源代码,而IIRC,cpython在寻找交叉点时总是遍历较小的集合。所以你有什么工作,但如果's'更长,这将返回'b'。 – senderle

+0

@senderle:我认为你是对的 - [源代码集](http://svn.python.org/projects/python/trunk/Objects/setobject.c)。然后我的第二种方法失败了,所以我删除它。感谢您指出。 –

0

如果你只有mysetb,然后从这个角度来看,您将无法访问a,因为它不存在。如果您创建多个可变对象并将其中的一个添加到myset,那么当您处理仅myset或您添加的对象时,其他人不会“知道”。

如果你想修改ab那么你需要跟踪两个对象的某个地方。

0

也许这:

(myset - (myset - set([b]))).pop() is a 
+0

它的工作原理,但设置的差异(即第一个)很可能需要Python逐个删除所有元素。正因为如此,它慢慢地迭代遍历整个集合。 – emu

+0

@emu:也许,虽然我猜可能会对边缘情况进行一些优化。无论如何,我担心这是使用_only_集合的唯一方法,不要诉诸于字典或线性搜索。 – georg