Acerca de list
Primero, un punto muy importante, del que todo seguirá (espero).
En Python ordinario, list
no es especial de ninguna manera (excepto tener una linda sintaxis para la construcción, que es principalmente un accidente histórico). Una vez que se hace una lista [3,2,6]
, es para todos los propósitos y propósitos solo un objeto Python ordinario, como un número 3
, un conjunto {3,7}
o una función lambda x: x+5
.
(Sí, admite el cambio de sus elementos, y admite la iteración, y muchas otras cosas, pero eso es exactamente lo que es un tipo: admite algunas operaciones, mientras que no admite otras. Int admite elevar a un poder, pero eso no que sea muy especial, es justo lo que es un int. lambda admite llamadas, pero eso no lo hace muy especial, para eso es lambda, después de todo :).
Acerca de and
and
no es un operador (puede llamarlo "operador", pero también puede llamar "para" un operador :). Los operadores en Python son (implementados mediante) métodos llamados a objetos de algún tipo, generalmente escritos como parte de ese tipo. No hay forma de que un método mantenga una evaluación de algunos de sus operandos, pero and
puede (y debe) hacer eso.
La consecuencia de eso es que and
no se puede sobrecargar, al igual for
que no se puede sobrecargar. Es completamente general y se comunica a través de un protocolo específico. Lo que puede hacer es personalizar su parte del protocolo, pero eso no significa que pueda alterar el comportamiento deand
completo. El protocolo es:
Imagine a Python interpretando "ayb" (esto no sucede literalmente de esta manera, pero ayuda a comprender). Cuando se trata de "y", observa el objeto que acaba de evaluar (a) y le pregunta: ¿es verdad? ( NO : ¿lo eres True
?) Si eres autor de una clase, puedes personalizar esta respuesta. Si a
responde "no", and
(omite b por completo, no se evalúa en absoluto y) dice: a
es mi resultado ( NO : Falso es mi resultado).
Si a
no responde, and
pregunta: ¿cuál es su longitud? (Nuevamente, puede personalizar esto como autor de a
la clase). Si la a
respuesta es 0, and
hace lo mismo que arriba: lo considera falso ( NO falso), omite by da a
como resultado.
Si a
responde algo distinto de 0 a la segunda pregunta ("cuál es su longitud"), o no responde en absoluto, o responde "sí" a la primera ("¿es verdad?"), and
Evalúa b, y dice: b
es mi resultado. Tenga en cuenta que lo hace NO preguntar b
a cualquier pregunta.
La otra forma de decir todo esto es que a and b
es casi lo mismo que b if a else a
, excepto que a se evalúa solo una vez.
Ahora siéntese unos minutos con un bolígrafo y papel, y convénzase que cuando {a, b} es un subconjunto de {Verdadero, Falso}, funciona exactamente como cabría esperar de los operadores booleanos. Pero espero haberte convencido de que es mucho más general y, como verás, mucho más útil de esta manera.
Poniendo esos dos juntos
Ahora espero que entienda su ejemplo 1. and
no le importa si mylist1 es un número, lista, lambda o un objeto de una clase Argmhbl. Solo le importa la respuesta de mylist1 a las preguntas del protocolo. Y, por supuesto, mylist1 responde 5 a la pregunta sobre la longitud, por lo que devuelve mylist2. Y eso es. No tiene nada que ver con elementos de mylist1 y mylist2: no ingresan a la imagen en ningún lugar.
Segundo ejemplo: &
enlist
Por otro lado, &
es un operador como cualquier otro, como +
por ejemplo. Se puede definir para un tipo definiendo un método especial en esa clase. int
lo define como bit a bit "y", y bool lo define como lógico "y", pero esa es solo una opción: por ejemplo, los conjuntos y algunos otros objetos, como las vistas de teclas dict, lo definen como una intersección de conjuntos. list
simplemente no lo define, probablemente porque Guido no pensó en ninguna forma obvia de definirlo.
numpy
Por otro lado: -D, las matrices numpy son especiales, o al menos están tratando de serlo. Por supuesto, numpy.array es solo una clase, no puede anular and
de ninguna manera, por lo que hace la siguiente mejor cosa: cuando se le pregunta "¿es verdad?", Numpy.array plantea un ValueError, efectivamente diciendo "por favor reformule la pregunta, mi la visión de la verdad no se ajusta a su modelo ". (Tenga en cuenta que el mensaje de ValueError no habla and
, porque numpy.array no sabe quién le hace la pregunta; solo habla de la verdad).
Para &
, es una historia completamente diferente. numpy.array puede definirlo como lo desee, y se define de manera &
consistente con otros operadores: pointwise. Entonces finalmente obtienes lo que quieres.
HTH
np.bitwise_and()
ynp.logical_and()
amigos para evitar confusiones.