¿Por qué los conjuntos de Python no entienden '+'?

90

Me gustaría saber por qué esto es válido:

set(range(10)) - set(range(5))

pero esto no es válido:

set(range(10)) + set(range(5))

¿Es porque '+' podría significar tanto intersección como unión?

badzil
fuente
3
|significa unión. ¿Que estas preguntando?
S.Lott
13
Es porque Guido eligió diferentes operadores para intersección y unión.
David Heffernan
3
@David Heffernan, Guido no suele hacer las cosas sin una razón o al menos algún principio rector; eso es lo que hace que Python sea tan bueno.
Mark Ransom
1
@ Mark Oh, estoy bastante seguro de que lo hizo por una buena razón.
David Heffernan
1
Si solo ~fuera un operador binario, entonces podría tener |para + unión y ~para diferencia, que es mucho más equilibrado.
Matt Joiner

Respuestas:

109

Los conjuntos de Python no tienen una implementación para el +operador.

Puede utilizar |para unión de conjuntos y &para intersección de conjuntos.

Los conjuntos se implementan -como diferencia de conjuntos. También puede usar ^para diferencia de conjuntos simétricos (es decir, devolverá un nuevo conjunto con solo los objetos que aparecen en un conjunto pero no aparecen en ambos conjuntos).

Platino azur
fuente
2
Gracias. No sabía sobre | y &.
badzil
99

Python eligió usar en |lugar de +porque la unión de conjuntos es un concepto que está estrechamente relacionado con la disyunción booleana; Los vectores de bits (que en python son simplemente int/ long) definen esta operación en una secuencia de valores booleanos y la llaman "bit a bit o". De hecho, esta operación es tan similar a la unión de conjuntos que los enteros binarios a veces también se denominan "conjuntos de bits", donde los elementos del conjunto se toman como números naturales.

Debido a que intya define operadores de tipo conjunto como |, &y ^, era natural que el settipo más nuevo usara la misma interfaz.

SingleNegationElimination
fuente
7
Creo que esta respuesta aborda mejor el "por qué" de la pregunta.
Greg Hendershott
1
Probablemente. +1 por el por qué. Sin embargo, en cierto sentido, al menos el autor de la pregunta parecía satisfecho con saber cómo hacer unión e intersección.
Platinum Azure
2
@Platinum: Me gusta responder a la pregunta que realmente se hizo, para que cuando llegue alguien más que tenga esa pregunta pueda ver todas las respuestas razonables; incluso si la persona que hizo la pregunta original ha seguido adelante. Entre los dos, lo respondemos bien.
SingleNegationElimination
1
@TokenMacGuy: "Porque Python simplemente no definió el operador" también responde el por qué. :-P
Platinum Azure
15
No estoy seguro de que lo haga; "Porque es azul" no explica "¿Por qué el cielo es azul?"
SingleNegationElimination
36

En la teoría de conjuntos, el símbolo + normalmente indica la unión disjunta de dos conjuntos. Si A y B son conjuntos, su unión disjunta se define como el conjunto

A + B = {(a, 1) | a in A} U {(b, 2) | b in B}

es decir, para construir la unión disjunta, marcamos todos los elementos de A y todos los elementos de B con etiquetas diferentes (en el ejemplo usé los números 1 y 2, pero dos "cosas" diferentes harían el trabajo) y luego tomamos el unión de los dos conjuntos resultantes. En el ejemplo anterior, he utilizado 'U' para la unión de conjuntos para que sea más similar a la notación matemática habitual; a continuación utilizo la notación de Python, es decir, '|' para unión y '&' para intersección.

Si A y B son disjuntos, A + B tiene una correspondencia de 1 a 1 con A | B. Si no es así, entonces todos los elementos comunes x en A y B aparecen dos veces en A + B: una vez como (x, 1) y una vez como (x, 2).

Entonces, dado que el símbolo '+' tiene un significado bastante bien establecido como una operación de conjunto, me parece muy consistente que Python no use este símbolo para la unión o intersección de conjuntos. Probablemente los diseñadores de Python tenían esto en mente cuando eligieron operadores de conjuntos.

Giorgio
fuente
5
Ésta es la respuesta óptima. Hasta que leí esta respuesta, entendí por qué Guido sobrecargó al |operador para uniones de conjuntos, pero no entendí por qué Guido también evitaba sobrecargar al +operador para uniones de conjuntos. Después de todo, hacerlo habría preservado la ortogonalidad con el +operador sobrecargado para adiciones a la lista. Dado que el sello distintivo de Python es la conformidad con la notación matemática (por ejemplo, que jdenota el componente complejo de números complejos), la curiosa elección de Guido finalmente tiene sentido.
Cecil Curry
23

Claro, podrían haber +hecho una unión, pero luego todavía necesitarían un símbolo para la intersección. |para unión es simétrica con &para intersección y por lo tanto hace una mejor elección.

Mark Ransom
fuente
10

Porque |significa unión y &significa intersección. Claramente, no hay razón para agregar varios operadores para la misma función.

Las razones para usar |y &probablemente se remontan a operaciones bit a bit. Si representa un conjunto como los bits en un número, esos son los operadores que usaría para hacer uniones e intersecciones.

+simple no está tan ligado a la unión y -es marcar la diferencia.

Winston Ewert
fuente
3

Porque la diferencia de conjuntos es un concepto muy útil y comúnmente conocido, pero no existe un concepto (de uso universal) de "suma de conjuntos".

Petr Viktorin
fuente
1
¿Unión? ¿Cuándo fue la última vez que escuchó a alguien decir "agregar suma" en lugar de "unión", o usar + en lugar de ∪ ?. A veces +se define como una adición de miembros . Algunos lo usan para diferencia simétrica . De cualquier manera, cualquier papel que lo use lo llama de otra manera o lo define primero.
Petr Viktorin
1
Alguien podría referirse a él como "suma de conjuntos" si no conoce el término adecuado. Obviamente, las personas que conocen el término "unión" utilizan el término "unión".
esponjoso