2012-06-17 75 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