2012-06-17 11 views
6

Supongo que tengo un conjunto myset de objetos personalizados que pueden ser iguales aunque sus referencias sean diferentes (a == b and a is not b). Ahora bien, si yo add(a) en el conjunto, Python asume correctamente que a in myset and b in myset aunque solo haya len(myset) == 1 objeto en el conjunto.Python: miembros de acceso de un conjunto

Eso está claro. ¿Pero ahora es posible extraer el valor de a de alguna manera del conjunto, usando b solamente? Supongamos que los objetos son mutables y quiero cambiarlos a ambos, habiendo olvidado la referencia directa al a. Dicho de otra manera, estoy buscando la operación myset[b], que devolvería exactamente el miembro a del conjunto.

Me parece que el tipo set no puede hacer esto (más rápido que iterar a través de todos sus miembros). Si es así, ¿hay al menos una solución efectiva?

+0

¿Por qué necesita para hacer esto? Si ya tiene 'b', ¿por qué necesita' a', que es igual? –

+0

Ese es un requisito fugly ... –

+0

@KarlKnechtel: el elemento dentro del conjunto se hace referencia desde otro lugar (desde dentro de una estructura profunda) y quiero cambiar su valor. Los objetos son básicamente de tipo vector 2D, y son mutables. – emu

Respuesta

5

No creo que set sea compatible con la recuperación de un elemento en O (1) vez, pero podría usar un dict en su lugar.

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

De hecho, trabajé con esto y miré la fuente hace un tiempo, y IIRC, cpython siempre itera sobre el conjunto más pequeño al buscar intersecciones. Entonces, lo que tienes funciona, pero si 's' es más largo, esto devolverá' b'. – senderle

+0

@senderle: Creo que tienes razón - [fuente del conjunto] (http://svn.python.org/projects/python/trunk/Objects/setobject.c).Entonces mi segundo enfoque falla, así que lo borro. Gracias por mencionarlo. –

0

Si sólo tiene mysetb y, a continuación, a partir de ese punto de vista, no tendrá acceso a a porque no está allí. Si crea varios objetos mutables y agrega uno de ellos al myset, los otros no son 'conocidos' cuando se trata solo de myset o del objeto que ha agregado.

Si desea modificar a y b, debe realizar un seguimiento de ambos objetos en alguna parte.

0

Tal vez esto:

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

Funciona, pero la diferencia establecida (es decir, la primera) probablemente requiera que Python elimine todos los elementos uno por uno. Debido a eso, es asintóticamente la misma lenta que iterar a través del conjunto. – emu

+0

@emu: tal vez, aunque supongo que puede haber algunas optimizaciones para casos extremos. De todos modos, me temo que esta es la única forma de usar _only_ sets, sin recurrir a los dicts o la búsqueda lineal. – georg

Cuestiones relacionadas