À propos list
D'abord un point très important, d'où tout découlera (j'espère).
En Python ordinaire, ce list
n'est en aucun cas spécial (sauf avoir une syntaxe mignonne pour la construction, ce qui est principalement un accident historique). Une fois qu'une liste [3,2,6]
est faite, c'est à toutes fins utiles juste un objet Python ordinaire, comme un nombre 3
, un ensemble {3,7}
ou une fonction lambda x: x+5
.
(Oui, il prend en charge la modification de ses éléments, et il prend en charge l'itération, et bien d'autres choses, mais c'est exactement ce qu'est un type: il prend en charge certaines opérations, sans en supporter d'autres. Int prend en charge l'élévation à une puissance, mais ce n'est pas le cas rendez-le très spécial - c'est exactement ce qu'est un int. lambda prend en charge les appels, mais cela ne le rend pas très spécial - c'est à cela que sert lambda, après tout :).
À propos and
and
n'est pas un opérateur (vous pouvez l'appeler "opérateur", mais vous pouvez également appeler "for" un opérateur :). Les opérateurs en Python sont (implémentés via) des méthodes appelées sur des objets d'un certain type, généralement écrits dans le cadre de ce type. Il n'y a aucun moyen pour une méthode de tenir une évaluation de certains de ses opérandes, mais and
peut (et doit) le faire.
La conséquence de cela est que and
cela ne peut pas être surchargé, tout comme for
ne peut pas être surchargé. Il est complètement général et communique via un protocole spécifié. Ce que vous pouvez faire est de personnaliser votre partie du protocole, mais cela ne signifie pas que vous pouvez modifier and
complètement le comportement de . Le protocole est:
Imaginez Python interprétant "a et b" (cela ne se produit pas littéralement de cette façon, mais cela aide à comprendre). Quand il s'agit de "et", il regarde l'objet qu'il vient d'évaluer (a), et lui demande: êtes-vous vrai? ( PAS : l'êtes-vous True
?) Si vous êtes un auteur de la classe de a, vous pouvez personnaliser cette réponse. Si a
répond «non», and
(saute complètement b, il n'est pas évalué du tout, et) dit: a
est mon résultat ( PAS : faux est mon résultat).
Si a
ne répond pas, and
lui demande: quelle est votre longueur? (Encore une fois, vous pouvez personnaliser cela en tant qu'auteur de a
la classe de). Si la a
réponse est 0, and
fait la même chose que ci-dessus - considère que c'est faux ( PAS faux), saute b et donne a
comme résultat.
Si a
répond autre chose que 0 à la deuxième question ("quelle est votre longueur"), ou s'il ne répond pas du tout, ou s'il répond "oui" à la première ("êtes-vous vrai"), and
évalue b, et dit: b
est mon résultat. Notez qu'il ne pose PASb
de questions.
L'autre façon de dire tout cela est que a and b
c'est presque la même chose que b if a else a
, sauf que a n'est évalué qu'une seule fois.
Maintenant, asseyez-vous pendant quelques minutes avec un stylo et du papier, et convainquez-vous que lorsque {a, b} est un sous-ensemble de {True, False}, cela fonctionne exactement comme vous vous attendez des opérateurs booléens. Mais j'espère vous avoir convaincu que c'est beaucoup plus général, et comme vous le verrez, beaucoup plus utile de cette façon.
Mettre ces deux ensemble
J'espère que vous comprenez votre exemple 1. and
ne se soucie pas si mylist1 est un nombre, une liste, un lambda ou un objet d'une classe Argmhbl. Il se soucie juste de la réponse de mylist1 aux questions du protocole. Et bien sûr, mylist1 répond à 5 à la question sur la longueur, donc et renvoie mylist2. Et c'est tout. Cela n'a rien à voir avec les éléments de mylist1 et mylist2 - ils n'entrent nulle part dans l'image.
Deuxième exemple: &
surlist
En revanche, &
c'est un opérateur comme les autres, comme +
par exemple. Il peut être défini pour un type en définissant une méthode spéciale sur cette classe. int
le définit comme "et" au niveau du bit, et bool le définit comme "et" logique, mais ce n'est qu'une option: par exemple, les ensembles et certains autres objets comme les vues de clés dict le définissent comme une intersection d'ensemble. list
ne le définit tout simplement pas, probablement parce que Guido n'a pensé à aucun moyen évident de le définir.
engourdi
De l'autre côté: -D, les tableaux numpy sont spéciaux, ou du moins ils essaient de l'être. Bien sûr, numpy.array est juste une classe, il ne peut and
en aucun cas remplacer , donc il fait la meilleure chose suivante: quand on lui demande "êtes-vous vrai", numpy.array lève une ValueError, en disant effectivement "veuillez reformuler la question, mon la vision de la vérité ne rentre pas dans votre modèle ». (Notez que le message ValueError ne parle pas and
- car numpy.array ne sait pas qui lui pose la question; il parle juste de la vérité.)
Car &
, c'est une histoire complètement différente. numpy.array peut le définir comme il le souhaite, et il définit de manière &
cohérente avec les autres opérateurs: point par point. Donc, vous obtenez enfin ce que vous voulez.
HTH,
np.bitwise_and()
etnp.logical_and()
et des amis pour éviter toute confusion.