2012-01-29 22 views
46

De acuerdo con mi interpretación de Python 2.7.2 documentación para Built-In Types 5.7 Set Types, debería ser posible eliminar los elementos del conjunto A de la serie B al pasar de A a set.remove(elem) o set.discard(elem)Python Extraiga el conjunto del conjunto

De la documentación 2.7.2:

nota, el argumento elem a la __contains__(), remove() y discard() métodos pueden ser un conjunto.

I interpretan que esto quiere decir que puede pasar un set-remove(elem) o discard(elem) y todos aquellos elementos serán eliminados a partir del conjunto de destino. Usaría esto para hacer algo extraño como eliminar todas las vocales de una cadena o remove all common words from a word-frequency historam. Aquí está el código de prueba:

Python 2.7.2 (default, Jun 12 2011, 14:24:46) [M... 
Type "help", "copyright", "credits" or "license" 
>>> a = set(range(10)) 
>>> b = set(range(5,10)) 
>>> a 
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 
>>> b 
set([8, 9, 5, 6, 7]) 
>>> a.remove(b) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
KeyError: set([8, 9, 5, 6, 7]) 
>>> a.discard(b) 
>>> a 
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 
>>> 

que espero volver:

>>> a 
set([0, 1, 2, 3, 4]) 

sé que puedo lograr esto con a.difference(b) que devuelve un nuevo conjunto; o con un set.difference_update(other); o con los operadores de conjuntos a -= b, que modifican el conjunto in situ.

¿Esto es un error en la documentación? ¿Puede set.remove(elem) en realidad no tomar un conjunto como argumento? ¿O la documentación se refiere a conjuntos de conjuntos? Dado que difference_update realiza mi interpretación, supongo que el caso es el último.

¿No es lo suficientemente claro?

EDITAR Después de 3 años de (algunos profesionales) el trabajo pitón adicional, y siendo elaborado recientemente de nuevo a esta pregunta, me doy cuenta ahora de lo que en realidad estaba tratando de hacer podría lograrse con:

>>> c = a.difference(b) 
set([0,1,2,3,4]) 

que es lo que originalmente estaba tratando de conseguir.

+2

¡Me encantaría que volvieras a esto tantos años después! +1 –

Respuesta

16

Usted ya ha respondido la pregunta. Se refiere a conjuntos de conjuntos (en realidad conjuntos que contienen conjuntos congelados).

The paragraph you are referring to comienza con:

Nota, el argumento elem a las __contains __(), remove(), y de descarte() métodos pueden ser un conjunto.

lo que significa que b en a.remove(b) puede ser un conjunto, y luego continúa con:

Para apoyar la búsqueda de un frozenset equivalente, el conjunto elem está mutado temporalmente durante la búsqueda y luego se restaura . Durante la búsqueda, el conjunto de elementos no debe leerse ni mutarse, ya que no tiene un valor significativo.

que significa que si b es un conjunto, a.remove(b) escaneará a para un frozenset equivalente a b y extraerla (o lanzar una KeyError si no existe).

+0

¡Gracias! Dada mi mala interpretación, esa segunda oración no tenía mucho sentido. Elegir esto como la respuesta principal ya que ayuda a aclarar cuál fue mi principal malentendido. El ejemplo de Ling también fue muy útil. – cod3monk3y

1

Creo que la documentación se refiere a conjuntos de conjuntos (congelados), sí.

+2

Pero no puede tener un conjunto de conjuntos; los conjuntos no son lavables Podrías tener un set con un frozenset como elemento, supongo. – DSM

+2

@DSM - de ahí por qué la documentación menciona que el valor de 'elem' está mutado durante la llamada para ver si hay un 'frozenset' equivalente. – Amber

+0

Ah, ya veo. Eso tiene sentido. +1. – DSM

7

No puede tener set s de set s en Python como set es mutable. En cambio, puede tener set s de frozenset s. Por otro lado, puede llamar al __contains__(), remove() y discard() con un set. Vea este ejemplo:

a = set([frozenset([2])]) 
set([2]) in a  # you get True 
a.remove(set([2])) # a is now empty 

Así que la respuesta a su pregunta es que la documentación se refiere a set s de frozenset s.

+0

Muy bonita ilustración concisa de lo que es, para mí, una parte inusualmente poco clara de la documentación de Python. Gracias Ling! – cod3monk3y

2

Estoy viendo la ayuda integrada para varias versiones de python (para mac). Aquí están los resultados.

  • python2.5

remove (...)
eliminar un elemento de un conjunto; debe ser un miembro.
Si el elemento no es miembro, genera un KeyError.

  • python2.6

remove (...)
eliminar un elemento de un conjunto; debe ser un miembro. Si el elemento no es miembro, genera un KeyError.

  • python2.7

remove (...)
eliminar un elemento de un conjunto; debe ser un miembro. Si el elemento no es miembro, genera un KeyError.

La documentación que se refieren a, en su totalidad, en realidad dice:

Nota, el argumento elem a los __contains__(), remove() y discard() métodos puede ser un conjunto. Para apoyar la búsqueda de un juego frozenset equivalente, el conjunto de elementos se muta temporalmente durante la búsqueda y luego se restaura.

Esto parece ser una nota al pie, que sugiere que el argumento puede ser un conjunto, pero a menos que encuentre un conjunto congelado coincidente dentro del conjunto, no se eliminará. La mención sobre el conjunto que se está modificando es tal que puede procesarse para buscar un conjunto congelado coincidente.

Cuestiones relacionadas