Sobre list
Primeiro, um ponto muito importante, do qual tudo se seguirá (espero).
No Python comum, list
não é especial de forma alguma (exceto ter uma sintaxe atraente para a construção, que é principalmente um acidente histórico). Depois que uma lista [3,2,6]
é feita, ela é, para todos os efeitos, apenas um objeto Python comum, como um número 3
, conjunto {3,7}
ou função lambda x: x+5
.
(Sim, ele suporta a alteração de seus elementos, e suporta iteração e muitas outras coisas, mas isso é exatamente o que é um tipo: suporta algumas operações, enquanto não suporta outras. Int suporta aumentar a potência, mas isso não Torne-o muito especial - é exatamente o que é um int O lambda suporta chamadas, mas isso não o torna muito especial - é para isso que serve o lambda, afinal :).
Sobre and
and
não é um operador (você pode chamá-lo de "operador", mas pode chamar "de" um operador também :). Operadores em Python são (implementados por) métodos chamados em objetos de algum tipo, geralmente escritos como parte desse tipo. Não há como um método realizar uma avaliação de alguns de seus operandos, mas and
pode (e deve) fazer isso.
A conseqüência disso é que and
não pode ser sobrecarregado, assim como for
não pode ser sobrecarregado. É completamente geral e se comunica através de um protocolo especificado. O que você pode fazer é personalizar sua parte do protocolo, mas isso não significa que você pode alterar and
completamente o comportamento . O protocolo é:
Imagine Python interpretando "aeb" (isso não acontece literalmente dessa maneira, mas ajuda a entender). Quando se trata de "e", olha para o objeto que acabou de avaliar (a) e pergunta: você é verdadeiro? ( NÃO : você é True
?) Se você é um autor de uma classe, pode personalizar esta resposta. Se a a
resposta for "não", and
(ignora b completamente, não é avaliada e) diz: a
é o meu resultado ( NOT : False é o meu resultado).
Se a
não responde, and
pergunta: qual é o seu comprimento? (Novamente, você pode personalizar isso como um autor da a
classe). Se a
responder 0, and
faz o mesmo que acima - considera falso ( NÃO Falso), pula be dá a
como resultado.
Se a
responder algo diferente de 0 à segunda pergunta ("qual é o seu tamanho"), ou não responder, ou responder "sim" à primeira ("você é verdadeiro"), and
avaliará b e diz: b
é o meu resultado. Observe que ele NÃO faz b
nenhuma pergunta.
A outra maneira de dizer tudo isso é a and b
quase igual b if a else a
, exceto que a é avaliada apenas uma vez.
Agora sente-se por alguns minutos com caneta e papel e convença-se de que quando {a, b} é um subconjunto de {True, False}, ele funciona exatamente como você esperaria dos operadores booleanos. Mas espero ter convencido você de que é muito mais geral e, como você verá, muito mais útil dessa maneira.
Juntando esses dois
Agora espero que você entenda o exemplo 1. and
não se importa se mylist1 é um número, lista, lambda ou um objeto de uma classe Argmhbl. Ele se importa apenas com a resposta da mylist1 às perguntas do protocolo. E, claro, mylist1 responde 5 à pergunta sobre comprimento, e retorna mylist2. E é isso. Não tem nada a ver com os elementos mylist1 e mylist2 - eles não aparecem na imagem em nenhum lugar.
Segundo exemplo: &
emlist
Por outro lado, &
é um operador como outro qualquer, como +
por exemplo. Pode ser definido para um tipo, definindo um método especial nessa classe. int
define-o como bit a bit "e", e bool define-o como lógico "e", mas isso é apenas uma opção: por exemplo, conjuntos e alguns outros objetos, como visualizações de teclas de ditado, definem-no como uma interseção de conjunto. list
simplesmente não define, provavelmente porque Guido não pensou em nenhuma maneira óbvia de defini-lo.
entorpecido
Por outro lado: -D, matrizes numpy são especiais, ou pelo menos estão tentando ser. Obviamente, numpy.array é apenas uma classe, não pode substituir de and
forma alguma, e faz a melhor coisa: quando perguntado "você é verdadeiro", numpy.array gera um ValueError, dizendo efetivamente "por favor, refaça a pergunta, meu visão da verdade não se encaixa no seu modelo ". (Observe que a mensagem ValueError não fala and
- porque numpy.array não sabe quem está fazendo a pergunta; apenas fala sobre a verdade.)
Pois &
, é uma história completamente diferente. numpy.array pode defini-lo como desejar e define &
consistentemente com outros operadores: pointwise. Então você finalmente consegue o que quer.
HTH,
np.bitwise_and()
enp.logical_and()
e amigos para evitar confusão.