Divisione Python


133

Stavo cercando di normalizzare un set di numeri da -100 a 0 a un intervallo di 10-100 e stavo riscontrando problemi solo per notare che anche senza nessuna variabile, questo non valuta il modo in cui mi aspetterei che:

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

La divisione Float non funziona neanche:

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

Se uno dei lati della divisione viene lanciato su un float funzionerà:

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

Ciascuna parte del primo esempio sta valutando come un int, il che significa che la risposta finale verrà lanciata in un int. Poiché 0,111 è inferiore a 0,5, arrotondato a 0. Non è trasparente secondo me, ma immagino che sia così.

Qual è la spiegazione?



3
Adam, non mi piace ancora la tua spiegazione. Il primo esempio è la divisione intera, che restituisce semplicemente 0. Il secondo esempio è tra parentesi erroneamente per l'effetto desiderato.
Presidente James K. Polk,

@GregS Il primo esempio è stato il problema. Il secondo esempio è esplicativo ed è stato scritto dopo la prima domanda. Tutte le risposte che seguono spiegano molto bene il problema, specialmente quelle di @KennyTM. È importante notare che il mio problema originale è solo un problema su Python 2.x, non 3. È un po 'sconcertante che il comportamento cambierà così, ma ora che lo so, userò dalla futura divisione di importazione e userò il 3 .x comportamento. Saluti.
Adam Nelson,

1
Adam, per favore, correggi il tuo ultimo EDIT. La parte destra non ha nulla di speciale; affinché una divisione sia mobile, il numeratore o il denominatore (o entrambi) devono essere mobili. Se pensi di aver letto nei documenti che la parte destra deve essere float, allora o la documentazione è mal formulata e deve essere corretta, o l'hai fraintesa. Hai visto un esempio, forse, e poi estrapolarne una regola?
tzot,

Risposte:


246

Stai usando Python 2.x, dove le divisioni intere troncano invece di diventare un numero in virgola mobile.

>>> 1 / 2
0

Dovresti renderne uno uno float:

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

oppure from __future__ import division, quali le forze /per adottare il comportamento di Python 3.x che restituisce sempre un valore a virgola mobile.

>>> from __future__ import division
>>> (10 - 20) / (100 - 10)
-0.1111111111111111

10
Se lo usi from __future__ import divisionpuoi ottenere il vecchio comportamento di divisione in stile C usando due barre (ad es. 1 // 2Si tradurrà in 0). Vedi Pep 238 Cambio operatore divisione
Utente

1
@Utente Non è necessaria l'importazione da __future__. In entrambi Python 2 e 3 //fa riferimento per __floordiv__()impostazione predefinita.
Casimir,

21

Stai inserendo Integer in modo che Python ti restituisca un intero :

>>> 10 / 90
0

Se successivamente lo lanci su un float, l'arrotondamento sarà già stato fatto, in altre parole, 0 intero diventerà sempre 0 float.

Se usi float su entrambi i lati della divisione, Python ti darà la risposta che ti aspetti.

>>> 10 / 90.0
0.1111111111111111

Quindi nel tuo caso:

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

11

Devi cambiarlo in un float PRIMA di fare la divisione. Questo è:

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

4
@Adam Nelson: funziona correttamente per me. Controlla le parentesi.
Fred Larson,

In realtà, mi sbaglio, ma dopo aver visto i documenti, si dovrebbe prima scegliere il lato destro.
Adam Nelson,

10
@Adam: non importa da che parte per primo.
kennytm,

11

In Python 2.7, l' /operatore è una divisione intera se gli input sono numeri interi:

>>>20/15
1

>>>20.0/15.0
1.33333333333

>>>20.0/15
1.33333333333

In Python 3.3, l' /operatore è una divisione float anche se gli input sono interi.

>>> 20/15
1.33333333333

>>>20.0/15
1.33333333333

Per la divisione di numeri interi in Python 3, utilizzeremo l' //operatore.

L' //operatore è un operatore di divisione intera in Python 2.7 e Python 3.3.

In Python 2.7 e Python 3.3:

>>>20//15
1

Ora guarda il confronto

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

Per il programma precedente, l'output sarà False in Python 2.7 e True in Python 3.3.

In Python 2.7 a = 1.75 e b = 1.

In Python 3.3 a = 1.75 eb = 1.75, proprio perché /è una divisione float.


8

Ha a che fare con la versione di Python che usi. Fondamentalmente adotta il comportamento C: se dividi due numeri interi, i risultati saranno arrotondati per difetto a un numero intero. Inoltre, tieni presente che Python esegue le operazioni da sinistra a destra, il che gioca un ruolo importante durante la digitazione.

Esempio: poiché questa è una domanda che mi viene sempre in mente quando faccio operazioni aritmetiche (dovrei convertirle in float e quale numero), viene presentato un esempio da quell'aspetto:

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

Quando dividiamo numeri interi, non a caso viene arrotondato per difetto.

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

Se digitiamo l'ultimo numero intero da float, avremo comunque zero, poiché quando il nostro numero viene diviso per il float è già diventato 0 a causa della divisione dei numeri interi.

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

Stesso scenario come sopra ma spostando il float tipecast un po 'più vicino al lato sinistro.

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

Alla fine, quando digitiamo il primo numero intero in virgola mobile, il risultato è quello desiderato, poiché a partire dalla prima divisione, ovvero quella più a sinistra, utilizziamo i float.

Extra 1: se si sta cercando di rispondere che per migliorare la valutazione aritmetica, si dovrebbe verificare questo

Extra 2: prestare attenzione al seguente scenario:

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

4

Specificare un float posizionando un '.' dopo che il numero causerà anche il float predefinito.

>>> 1 / 2
0

>>> 1. / 2.
0.5

2

Fai almeno uno di questi float, quindi sarà float division, non intero:

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

Lanciare il risultato su float è troppo tardi.


1

In Python cv2non aggiornato il calcolo della divisione. quindi, è necessario includere from __future__ import division nella prima riga del programma.


0

Ad ogni modo, è una divisione intera. 10/90 = 0. Nel secondo caso, stai semplicemente lanciando 0 su un float.

Prova a lanciare uno degli operandi di "/" come float:

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

0

Stai lanciando il float dopo che la divisione è già avvenuta nel tuo secondo esempio. Prova questo:

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

0

Sono un po 'sorpreso dal fatto che nessuno abbia menzionato che al poster originale potrebbero essere piaciuti i numeri razionali . Se dovessi essere interessato a questo, il programma basato su Python Sage ha le spalle . (Attualmente ancora basato su Python 2.x, anche se 3.x è in corso.)

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

Questa non è una soluzione per tutti, perché fa alcuni preparsing quindi questi numeri non sono ints, ma Integerelementi di classe Sage . Tuttavia, vale la pena menzionare come parte dell'ecosistema Python.


0

Personalmente ho preferito inserire un 1. *all'inizio. Quindi l'espressione diventa qualcosa del genere:

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

Come faccio sempre una divisione per una formula come:

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

quindi è impossibile semplicemente aggiungere un .0like 20.0. E nel mio caso, il wrapping con a float()potrebbe perdere un po 'di leggibilità.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.