2012-06-17 15 views
6

Dire che ho un set myset di oggetti personalizzati che possono essere uguali anche se i loro riferimenti sono diversi (a == b and a is not b). Ora se ho impostato il add(a) sul set, Python presuppone correttamente che a in myset and b in myset anche se nel set è presente solo l'oggetto len(myset) == 1.Python: accesso ai membri di un set

Questo è chiaro. Ma è ora possibile estrarre il valore di a in qualche modo dal set, usando solo ? Supponiamo che gli oggetti siano mutabili e voglio cambiarli entrambi, avendo dimenticato il riferimento diretto a a. In altre parole, sto cercando l'operazione myset[b], che restituirebbe esattamente il membro a del set.

Mi sembra che il tipo set non riesca a farlo (più veloce dell'iterazione di tutti i suoi membri). Se è così, c'è almeno un efficace work-around?

+0

Perché avete bisogno di fare questo? Se hai già 'b', perché hai bisogno di' a', che è uguale? –

+0

Questo è un requisito fugace ... –

+0

@KarlKnechtel: l'elemento all'interno del set viene referenziato da qualche altra parte (all'interno di una struttura profonda) e voglio cambiarne il valore. Gli oggetti sono fondamentalmente di tipo vettoriale 2D e sono mutabili. – emu

risposta

5

Non credo che il numero set supporti il ​​recupero di un elemento in O (1) ora, ma è possibile utilizzare un dict.

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

Infatti mi sono occupato di questo aspetto e ho guardato il sorgente qualche tempo fa, e IIRC, cpython esegue sempre un'iterazione sul set più piccolo quando si cercano le intersezioni. Quindi, quello che hai funziona, ma se 's' è più lungo, questo restituirà' b'. – senderle

+0

@senderle: Penso che tu abbia ragione - [source for set] (http://svn.python.org/projects/python/trunk/Objects/setobject.c).Poi il mio secondo approccio fallisce, quindi lo sto eliminando. Grazie per segnalarlo. –

0

Se avete solo myset e b, quindi da questo punto di vista, non avrete accesso a a perché non è lì. Se crei più oggetti mutabili e ne aggiungi uno a myset, gli altri non sono "noti" quando hai a che fare solo con myset o l'oggetto che hai aggiunto.

Se si desidera modificare a e b, è necessario tenere traccia di entrambi gli oggetti da qualche parte.

0

Forse questo:

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

Funziona, ma la differenza tra gli insiemi (ovvero la prima) probabilmente richiede che Python rimuova tutti gli elementi uno per uno. Per questo motivo, è asintoticamente lo stesso lento di iterare attraverso il set. – emu

+0

@emu: forse, anche se penso che potrebbero esserci alcune ottimizzazioni per i casi limite. Ad ogni modo, temo che questo sia l'unico modo per usare _only_ set, senza ricorrere a dict o ricerca lineare. – georg

Problemi correlati