Python-Division

133

Ich habe versucht, eine Reihe von Zahlen von -100 bis 0 auf einen Bereich von 10 bis 100 zu normalisieren, und hatte nur Probleme zu bemerken, dass dies selbst ohne Variablen nicht so bewertet, wie ich es erwarten würde:

>>> (20-10) / (100-10)
0

Die Float-Division funktioniert auch nicht:

>>> float((20-10) / (100-10))
0.0

Wenn eine Seite der Division auf einen Schwimmer geworfen wird, funktioniert dies:

>>> (20-10) / float((100-10))
0.1111111111111111

Jede Seite im ersten Beispiel wird als int ausgewertet, was bedeutet, dass die endgültige Antwort in ein int umgewandelt wird. Da 0,111 kleiner als 0,5 ist, wird auf 0 gerundet. Es ist meiner Meinung nach nicht transparent, aber ich denke, so ist es.

Was ist die Erklärung?

Adam Nelson
quelle
3
Adam, ich mag deine Erklärung immer noch nicht. Das erste Beispiel ist die Ganzzahldivision, die einfach 0 zurückgibt. Das zweite Beispiel ist für den gewünschten Effekt falsch in Klammern gesetzt.
Präsident James K. Polk
@ GregS Das erste Beispiel war das Problem. Das zweite Beispiel ist erklärend und wurde nach der ersten Frage geschrieben. Alle Antworten unten erklären das Problem sehr gut, insbesondere die von @KennyTM. Es ist wichtig zu beachten, dass mein ursprüngliches Problem nur ein Problem in Python 2.x ist, nicht in 3. Es ist ein wenig beunruhigend, dass sich das Verhalten so ändern wird, aber jetzt, da ich weiß, werde ich es aus der zukünftigen Importabteilung verwenden und die 3 verwenden .x Verhalten. Prost.
Adam Nelson
1
Adam, bitte korrigiere deine letzte BEARBEITUNG. Die rechte Seite hat nichts Besonderes; Damit eine Division float ist, muss entweder der Zähler oder der Nenner (oder beide) float sein. Wenn Sie glauben, in den Dokumenten gelesen zu haben, dass die rechte Seite schwebend sein muss, ist die Dokumentation entweder schlecht formuliert und sollte korrigiert werden, oder Sie haben sie falsch verstanden. Haben Sie vielleicht ein Beispiel gesehen und dann eine Regel daraus extrapoliert?
Zot

Antworten:

246

Sie verwenden Python 2.x, bei dem ganzzahlige Unterteilungen abgeschnitten werden, anstatt eine Gleitkommazahl zu werden.

>>> 1 / 2
0

Sie sollten einen von ihnen zu einem machen float:

>>> float(10 - 20) / (100 - 10)
-0.1111111111111111

oder from __future__ import division, was die Kräfte zwingt /, das Verhalten von Python 3.x zu übernehmen, das immer einen Float zurückgibt.

>>> from __future__ import division
>>> (10 - 20) / (100 - 10)
-0.1111111111111111
kennytm
quelle
10
Wenn Sie verwenden from __future__ import division, können Sie das alte Teilungsverhalten im C-Stil durch Verwendung von zwei Schrägstrichen erhalten (z. B. 1 // 2ergibt dies 0). Siehe Pep 238 Ändern des Divisionsoperators
Benutzer
1
@ Benutzer Keine Notwendigkeit für den Import von __future__. In beiden Python 2 und 3 //bezieht sich auf __floordiv__()standardmäßig.
Casimir
21

Sie setzen Ganzzahlen ein, sodass Python Ihnen eine Ganzzahl zurückgibt :

>>> 10 / 90
0

Wenn Sie dies später in einen Float umwandeln, wurde die Rundung bereits durchgeführt, mit anderen Worten, 0 Integer wird immer zu 0 Float.

Wenn Sie Floats auf beiden Seiten der Division verwenden, gibt Python Ihnen die Antwort, die Sie erwarten.

>>> 10 / 90.0
0.1111111111111111

Also in deinem Fall:

>>> float(20-10) / (100-10)
0.1111111111111111
>>> (20-10) / float(100-10)
0.1111111111111111
Dave Webb
quelle
11

Sie müssen es in einen Float ändern, bevor Sie die Division durchführen. Das ist:

float(20 - 10) / (100 - 10)
A. Levy
quelle
4
@ Adam Nelson: Funktioniert richtig für mich. Überprüfen Sie Ihre Klammern.
Fred Larson
Eigentlich irre ich mich - aber nachdem man sich die Dokumente angesehen hat, sollte man zuerst die rechte Seite werfen.
Adam Nelson
10
@ Adam: Es ist egal, welche Seite zuerst.
Kennytm
11

In Python 2.7 ist der /Operator eine Ganzzahldivision, wenn Eingaben Ganzzahlen sind:

>>>20/15
1

>>>20.0/15.0
1.33333333333

>>>20.0/15
1.33333333333

In Python 3.3 ist der /Operator eine Float-Division, auch wenn die Eingaben ganzzahlig sind.

>>> 20/15
1.33333333333

>>>20.0/15
1.33333333333

Für die Ganzzahldivision in Python 3 verwenden wir die // Operator.

Das // Operator ist sowohl in Python 2.7 als auch in Python 3.3 ein Ganzzahldivisionsoperator.

In Python 2.7 und Python 3.3:

>>>20//15
1

Sehen Sie sich jetzt den Vergleich an

>>>a = 7.0/4.0
>>>b = 7/4
>>>print a == b

Für das obige Programm ist die Ausgabe in Python 2.7 False und in Python 3.3 True.

In Python 2.7 ist a = 1,75 und b = 1.

In Python 3.3 ist a = 1,75 und b = 1,75, nur weil /es sich um eine Float-Division handelt.

Harsha Vardhan
quelle
8

Dies hängt mit der von Ihnen verwendeten Python-Version zusammen. Grundsätzlich wird das C-Verhalten übernommen: Wenn Sie zwei Ganzzahlen teilen, werden die Ergebnisse auf eine Ganzzahl abgerundet. Denken Sie auch daran, dass Python die Operationen von links nach rechts ausführt, was beim Typisieren eine Rolle spielt.

Beispiel: Da dies eine Frage ist, die mir bei arithmetischen Operationen immer im Kopf auftaucht (sollte ich in float konvertieren und welche Zahl), wird ein Beispiel aus diesem Aspekt vorgestellt:

>>> a = 1/2/3/4/5/4/3
>>> a
0

Wenn wir ganze Zahlen teilen, wird es nicht überraschend, dass sie niedriger gerundet werden.

>>> a = 1/2/3/4/5/4/float(3)
>>> a
0.0

Wenn wir die letzte zu schwebende Ganzzahl typisieren, erhalten wir immer noch Null, da zu dem Zeitpunkt, an dem unsere Zahl durch das Gleitkomma geteilt wird, aufgrund der Ganzzahldivision bereits 0 geworden ist.

>>> a = 1/2/3/float(4)/5/4/3
>>> a
0.0

Gleiches Szenario wie oben, jedoch Verschiebung des Float-Typs etwas näher an die linke Seite.

>>> a = float(1)/2/3/4/5/4/3
>>> a
0.0006944444444444445

Wenn wir schließlich die erste Ganzzahl eingeben, die schwebt, ist das Ergebnis das gewünschte, da wir ausgehend von der ersten Division, dh der ganz linken, Gleitkommazahlen verwenden.

Extra 1: Wenn Sie versuchen, dies zu beantworten, um die arithmetische Auswertung zu verbessern, sollten Sie dies überprüfen

Extra 2: Bitte beachten Sie das folgende Szenario:

>>> a = float(1/2/3/4/5/4/3)
>>> a
0.0
George
quelle
4

Angeben eines Floats durch Platzieren eines '.' Nach der Nummer wird es auch standardmäßig schweben.

>>> 1 / 2
0

>>> 1. / 2.
0.5
billmanH
quelle
2

Lassen Sie mindestens einen von ihnen schweben, dann wird es eine Float-Division sein, keine ganze Zahl:

>>> (20.0-10) / (100-10)
0.1111111111111111

Das Ergebnis zum Schweben zu bringen ist zu spät.

unbeli
quelle
1

In Python cv2nicht aktualisiert die Divisionsberechnung. Sie müssen also from __future__ import division in die erste Zeile des Programms aufnehmen.

Kavitha Raj
quelle
0

In jedem Fall ist es eine ganzzahlige Division. 10/90 = 0. Im zweiten Fall werfen Sie lediglich 0 auf einen Float.

Versuchen Sie, einen der Operanden von "/" als Float zu verwenden:

float(20-10) / (100-10)
Fred Larson
quelle
0

Sie werfen, um zu schweben, nachdem die Teilung bereits in Ihrem zweiten Beispiel stattgefunden hat. Versuche dies:

float(20-10) / float(100-10)
David M.
quelle
0

Ich bin etwas überrascht, dass niemand erwähnt hat, dass das Originalplakat möglicherweise rationale Zahlen ergeben hätte. Wenn Sie daran interessiert sind, hat das Python-basierte Programm Sage Ihren Rücken . (Derzeit basiert es noch auf Python 2.x, obwohl 3.x im Gange ist.)

sage: (20-10) / (100-10)
1/9

Dies ist nicht für jeden eine Lösung, da einige Vorbereitungen getroffen werden, sodass diese Zahlen nicht ints, sondern Sage- IntegerKlassenelemente sind. Erwähnenswert als Teil des Python-Ökosystems.

kcrisman
quelle
0

Persönlich habe ich es vorgezogen, 1. *ganz am Anfang ein einzufügen . Der Ausdruck wird also ungefähr so:

1. * (20-10) / (100-10)

Da mache ich immer eine Division für eine Formel wie:

accuracy = 1. * (len(y_val) - sum(y_val)) / len(y_val)

Es ist also unmöglich, einfach ein .0Like hinzuzufügen 20.0. Und in meinem Fall kann das Umwickeln mit a float()ein wenig an Lesbarkeit verlieren.

FredWe
quelle