Por que '+' não é compreendido por conjuntos Python?

91

Eu gostaria de saber por que isso é válido:

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

mas isso não é válido:

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

É porque '+' pode significar interseção e união?

badzil
fonte
3
|significa união. O que você está perguntando?
S.Lott,
14
É porque Guido escolheu operadores diferentes para interseção e união.
David Heffernan
3
@David Heffernan, Guido geralmente não faz as coisas sem uma razão ou pelo menos algum princípio orientador - é isso que torna o Python tão bom.
Mark Ransom,
1
@Mark Oh, tenho certeza de que ele fez isso por um bom motivo.
David Heffernan,
1
Se ~fosse apenas um operador binário, você poderia ter |para + união e ~para diferença, que é muito mais equilibrado.
Matt Joiner,

Respostas:

113

Os conjuntos Python não têm uma implementação para o +operador.

Você pode usar |para conjunto de união e &para conjunto de intersecção.

Conjuntos implementam -como diferença definida. Você também pode usar ^para diferença de conjunto simétrico (ou seja, ele retornará um novo conjunto com apenas os objetos que aparecem em um conjunto, mas não aparecem em ambos os conjuntos).

Platinum Azure
fonte
2
Obrigado. Eu não sabia sobre | e &.
badzil
100

Python optou por usar em |vez de +porque a união de conjuntos é um conceito intimamente relacionado à disjunção booleana; Os vetores de bits (que em python são apenas int/ long) definem essa operação em uma sequência de valores booleanos e a chamam de "bit a bit ou". Na verdade, essa operação é tão semelhante à união de conjuntos que os inteiros binários às vezes também são chamados de "Conjuntos de bits", em que os elementos do conjunto são considerados números naturais.

Como intjá define operadores semelhantes a conjuntos como |, &e ^, era natural que o settipo mais novo usasse a mesma interface.

SingleNegationElimination
fonte
7
Acho que essa resposta aborda melhor o "porquê" da pergunta.
Greg Hendershott,
1
Provavelmente. 1 para o porquê. Em certo sentido, porém, pelo menos o questionador parecia satisfeito apenas em saber como fazer a união e a interseção.
Platinum Azure
2
@Platinum: Gosto de responder às perguntas realmente feitas, para que quando alguém vier com essa pergunta possa ver todas as respostas razoáveis; mesmo que a pessoa que fez a pergunta original tenha seguido em frente. Entre nós dois, respondemos bem.
SingleNegationElimination
1
@TokenMacGuy: "Porque o Python simplesmente não definia o operador" também responde o porquê. :-P
Platinum Azure
15
Eu não tenho certeza disso; "Porque é azul" não explica "Por que o céu é azul?"
SingleNegationElimination
36

Na teoria dos conjuntos, o símbolo + normalmente indica a união disjunta de dois conjuntos. Se A e B são conjuntos, sua união disjunta é definida como o conjunto

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

ou seja, para construir a união disjunta, marcamos todos os elementos de A e todos os elementos de B com tags diferentes (no exemplo, usei os números 1 e 2, mas quaisquer duas "coisas" diferentes fariam o trabalho) e, em seguida, pegamos o união dos dois conjuntos resultantes. No exemplo acima, usei 'U' para união de conjuntos para torná-lo mais semelhante à notação matemática usual; abaixo, uso a notação Python, ou seja, '|' para união e '&' para interseção.

Se A e B são disjuntos, o A + B tem uma correspondência de 1 para 1 com A | B. Se não forem, todos os elementos comuns x em A e B aparecem duas vezes em A + B: uma vez como (x, 1) e uma vez como (x, 2).

Portanto, uma vez que o símbolo '+' tem um significado bem estabelecido como uma operação de conjunto, acho muito consistente que o Python não use este símbolo para união ou interseção de conjunto. Provavelmente, os designers Python tinham isso em mente quando escolheram os operadores de conjunto.

Giorgio
fonte
5
Esta é a resposta ideal. Até ler esta resposta, grocei por que Guido sobrecarregou o |operador para as uniões de conjuntos, mas não consegui grocar por que Guido evitou sobrecarregar o +operador também para as uniões de conjuntos. Afinal, fazer isso preservaria a ortogonalidade com o +operador sobrecarregado para adições à lista. Visto que a marca registrada do Python é a conformidade com a notação matemática (por exemplo, jdenotando o componente complexo dos números complexos), a escolha curiosa de Guido finalmente faz sentido.
Cecil Curry
23

Claro, eles poderiam ter usado +para fazer uma união, mas ainda precisariam de um símbolo para a interseção. |pois a união é simétrica com &a interseção e, portanto, é uma escolha melhor.

Mark Ransom
fonte
10

Porque |significa união e &significa intersecção. Claramente, não há razão para adicionar vários operadores para a mesma função.

As razões para usar |e &provavelmente remontam às operações bit a bit. Se você representar um conjunto como os bits em um número, esses são os operadores que você usaria para fazer a união e a interseção.

+o simples não está tão vinculado à união e -é definir a diferença.

Winston Ewert
fonte
3

Porque a diferença de conjuntos é um conceito muito útil e comumente conhecido, mas não existe um conceito (usado universalmente) de “adição de conjuntos”.

Petr Viktorin
fonte
1
União? Quando foi a última vez que você ouviu alguém dizer „definir adição“ em vez de „união“, ou usar + em vez de ∪ ?. Às vezes, +é definido como adição por membro . Alguns o usam para diferenças simétricas . De qualquer forma, qualquer papel que o use o chama de outra coisa ou o define primeiro.
Petr Viktorin,
1
Alguém pode se referir a isso como 'adição de conjunto' se não souber o termo adequado. Obviamente, as pessoas que conhecem o termo 'sindicato' usam o termo 'sindicato'.
fofo de