Über list
Zunächst ein sehr wichtiger Punkt, von dem aus alles folgen wird (hoffe ich).
In gewöhnlichem Python list
ist es in keiner Weise etwas Besonderes (außer eine niedliche Syntax zum Konstruieren zu haben, was meistens ein historischer Unfall ist). Sobald eine Liste [3,2,6]
erstellt wurde, handelt es sich in jeder Hinsicht nur um ein gewöhnliches Python-Objekt, z. B. eine Zahl 3
, eine Menge {3,7}
oder eine Funktion lambda x: x+5
.
(Ja, es unterstützt das Ändern seiner Elemente und es unterstützt die Iteration und viele andere Dinge, aber genau das ist ein Typ: Es unterstützt einige Operationen, während andere nicht unterstützt werden. Int unterstützt das Erhöhen auf eine Potenz, aber das tut es nicht mach es zu etwas ganz Besonderem - es ist genau das, was ein Int ist. Lambda unterstützt das Aufrufen, aber das macht es nicht zu etwas Besonderem - dafür ist Lambda schließlich :).
Über and
and
ist kein Operator (Sie können es "Operator" nennen, aber Sie können auch "für" einen Operator nennen :). Operatoren in Python sind (implementiert durch) Methoden, die für Objekte eines Typs aufgerufen werden und normalerweise als Teil dieses Typs geschrieben werden. Es gibt keine Möglichkeit für eine Methode, eine Auswertung einiger ihrer Operanden durchzuführen, aber sie and
kann (und muss) dies tun.
Die Folge davon ist, dass and
nicht überladen werden kann, genauso wie for
nicht überladen werden kann. Es ist vollständig allgemein und kommuniziert über ein bestimmtes Protokoll. Was Sie tun können , ist Ihren Teil des Protokolls anzupassen, aber das bedeutet nicht, dass Sie das Verhalten von and
vollständig ändern können . Das Protokoll lautet:
Stellen Sie sich vor, Python interpretiert "a und b" (dies geschieht nicht wörtlich auf diese Weise, aber es hilft beim Verständnis). Wenn es um "und" geht, betrachtet es das Objekt, das es gerade ausgewertet hat (a), und fragt es: Sind Sie wahr? ( NICHT : bist du True
?) Wenn du ein Autor der Klasse von a bist, kannst du diese Antwort anpassen. Wenn die a
Antwort "nein" and
lautet (b wird vollständig übersprungen, wird es überhaupt nicht ausgewertet und) lautet: a
ist mein Ergebnis ( NICHT : Falsch ist mein Ergebnis).
Wenn a
nicht antwortet, and
fragt es: Wie lang sind Sie? (Auch hier können Sie dies als Autor der a
Klasse anpassen .) Wenn die a
Antwort 0 lautet, and
wird dasselbe wie oben ausgeführt - betrachtet sie als falsch ( NICHT falsch), überspringt b und gibt a
als Ergebnis.
Wenn a
die zweite Frage mit etwas anderem als 0 beantwortet wird ("Was ist Ihre Länge?") Oder wenn die erste Frage überhaupt nicht beantwortet wird oder wenn die erste Frage mit "Ja" beantwortet wird (" Sind Sie wahr?"), and
Wird b und bewertet sagt: b
ist mein Ergebnis. Beachten Sie, dass es sich nicht fragen b
Fragen.
Die andere Art, dies alles zu sagen, a and b
ist fast die gleiche wie b if a else a
, außer dass a nur einmal ausgewertet wird.
Setzen Sie sich nun ein paar Minuten mit Stift und Papier hin und überzeugen Sie sich selbst, dass {a, b}, wenn es sich um eine Teilmenge von {True, False} handelt, genau so funktioniert, wie Sie es von Booleschen Operatoren erwarten würden. Aber ich hoffe, ich habe Sie davon überzeugt, dass es viel allgemeiner und, wie Sie sehen werden, auf diese Weise viel nützlicher ist.
Diese beiden zusammenfügen
Jetzt hoffe ich, dass Sie Ihr Beispiel verstehen 1. and
Es ist mir egal, ob mylist1 eine Zahl, eine Liste, ein Lambda oder ein Objekt einer Klasse Argmhbl ist. Es geht nur um die Antwort von mylist1 auf die Fragen des Protokolls. Und natürlich beantwortet mylist1 5 auf die Frage nach der Länge, also gibt mylist2 zurück. Und das ist es. Es hat nichts mit Elementen von mylist1 und mylist2 zu tun - sie kommen nirgendwo ins Bild.
Zweites Beispiel: &
einlist
Auf der anderen Seite &
ist ein Operator wie jeder andere, wie +
zum Beispiel. Sie kann für einen Typ definiert werden, indem eine spezielle Methode für diese Klasse definiert wird. int
definiert es als bitweise "und" und bool definiert es als logisch "und", aber das ist nur eine Option: Zum Beispiel definieren Mengen und einige andere Objekte wie Diktatschlüsselansichten es als Mengenschnittstelle. list
definiert es einfach nicht, wahrscheinlich weil Guido sich keine offensichtliche Art der Definition ausgedacht hat.
numpy
Auf der anderen Seite: -D, numpy Arrays sind etwas Besonderes oder versuchen es zumindest. Natürlich ist numpy.array nur eine Klasse, sie kann and
in keiner Weise überschrieben werden, also macht sie das nächstbeste: Wenn sie gefragt werden, ob Sie wahr sind, löst numpy.array einen ValueError aus und sagt effektiv: "Bitte formulieren Sie die Frage neu, meine." Sicht der Wahrheit passt nicht in Ihr Modell ". (Beachten Sie, dass in der ValueError-Nachricht nicht gesprochen wird, and
da numpy.array nicht weiß, wer die Frage stellt. Sie spricht nur über die Wahrheit.)
Denn &
es ist eine ganz andere Geschichte. numpy.array kann es so definieren, wie es möchte, und es definiert &
konsistent mit anderen Operatoren: pointwise. So bekommen Sie endlich, was Sie wollen.
HTH,
np.bitwise_and()
undnp.logical_and()
und Freunde, um Verwirrung zu vermeiden.