Frage

Ich lief in etwas Interessantes über den Python Augmented Zuordnung +=

scheint es, die automatische Datentypumwandlung zu sein ist nicht immer für a += b getan, wenn eine ist ein ‚einfacher‘ Datentyp, während a = a + b zur Arbeit scheint immer

Fälle, in denen die Konvertierung abgeschlossen ist

a = 1
b = 1j

a = 1
b = 0.5

Fall, in dem die Umwandlung nicht getan

from numpy import array
a = array([0, 0 ,0])
b = array([0, 0, 1j])

nach a += b, a verbleibt als ganzzahlige Matrix anstelle von komplexer Matrix

Früher dachte ich, a += b die gleiche wie a = a + b ist, was ist der Unterschied von ihnen in der zugrunde liegenden Implementierung?

War es hilfreich?

Lösung

Für den + Operator, Python definiert drei "besondere" Methoden, dass ein Objekt implementieren kann:

  • __add__: fügt zwei Elemente (+ Operator). Wenn Sie a + b tun, wird die __add__ Methode des a mit b als Argument genannt.
  • __radd__: reflektiert Add; für a + b wird die Methode des __radd__ b mit a als Beispiel genannt. Dies wird nur verwendet, wenn a nicht weiß, wie das Add zu tun, und die beiden Objekte sind verschiedene Typen.
  • __iadd__: in-place Add; für a += b verwendet, in denen das Ergebnis auf der linken Variablen zugewiesen zurück. Dies wird separat zur Verfügung gestellt, weil es möglich sein könnte, es in einer effizienteren Weise zu implementieren. wenn a eine Liste ist zum Beispiel, dann ist a += b die gleiche wie a.extend(b). Doch im Fall von c = a + b müssen Sie eine Kopie von a, bevor Sie es erweitern, da a ist in diesem Fall nicht geändert werden. Beachten Sie, dass, wenn Sie __iadd__ nicht implementieren dann Python wird __add__ einfach anrufen statt.

So, da diese verschiedenen Operationen mit separaten Methoden implementiert werden, ist es möglich (aber in der Regel schlechte Praxis), um sie zu implementieren, so dass sie ganz andere Dinge zu tun, oder vielleicht in diesem Fall nur leicht verschiedene Dinge .

Andere haben gefolgert, dass Sie NumPy verwenden und erklärt sein Verhalten. Allerdings bat Sie über die zugrunde liegende Implementierung. Hoffentlich sehen Sie jetzt Warum ist es manchmal der Fall, dass a += b nicht das gleiche wie a = a + b ist. By the way, kann auch ein ähnliches Trio von Methoden für andere Operationen durchgeführt werden. Siehe Diese Seite für eine Liste aller in-Place-Verfahren unterstützt.

Andere Tipps

Wenn array ist numpy.array (Sie eigentlich gar nicht angeben), dann ist das Problem, das passiert, ist, weil diese Arrays nicht ihre Art verändern kann. Wenn Sie das Array ohne Typspezifizierer schaffen, errät es einen Typ. Wenn Sie dann eine Operation zu tun versuchen, diese Art nicht unterstützt (wie es auf einen Typen mit einer größeren Domäne hinzufügen, wie komplex), weiß numpy die Berechnung durchführen, aber sie weiß auch, dass das Ergebnis nur in der Art gespeichert werden mit der größeren Domain. Es beschwert sich (auf meiner Maschine, wie auch immer, das erste Mal, dass ich so einen Auftrag zu tun), dass das Ergebnis nicht passt. Wenn Sie eine regelmäßige Zugabe tun, ein neues Array hat in jedem Fall durchgeführt werden, und numpy gibt es den richtigen Typ.

>>> a=numpy.array([1])
>>> a.dtype
dtype('int32')
>>> b=numpy.array([1+1j])
>>> b.dtype
dtype('complex128')
>>> a+b
array([ 2.+1.j])
>>> (a+b).dtype
dtype('complex128')
>>> a+=b
>>> a
array([2])
>>> a.dtype
dtype('int32')
>>> 

Der Unterschied zwischen a = a + b und a += b ist, dass dieser Zusatz wird, wann immer möglich, done „in-place“ das Mittel, durch das Objekt a ändern. Sie können dies leicht erkennen, mit Listen.

a = b = [1, 2]
a += [3]
print b # [1, 2, 3]
a = b = [1, 2]
a = a + [3]
print b # [1, 2]

Rafe Kettler Antwort ist richtig, aber es scheint, dass Sie es geschafft haben, a = erhalten [0,0,0], nachdem es zu b Zugabe (nach Ihrem Beitrag).

Nun, wenn Sie verwenden numpy oder scipy (ich sage das, weil ich array und Wunder sehen, was Array erstellt hier wird), dann ist die „normal“, und soll auch eine Warnung erhöhen:

ComplexWarning: Casting komplexe Werte an den realen verwirft den imaginären Teil

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top