2009-10-08 11 views
254

Ho visto questo nel codice di qualcuno:Qual è la ragione per avere '//' in Python?

y = img_index // num_images 

dove img_index è un indice di esecuzione e num_images è 3.

Quando ho pasticciare con // in IPython, sembra agire come un segno di divisione (cioè una barra in avanti). Mi stavo chiedendo se c'è qualche ragione per avere doppie barre in avanti?

risposta

318

In Python 3, l'operatore / eseguiva una divisione in virgola mobile e aggiungeva l'operatore // alla divisione integer (cioè il quoziente senza resto); mentre in Python 2, l'operatore / era semplicemente una divisione intera, a meno che uno degli operandi fosse già un numero in virgola mobile.

In Python 2.X:

>>> 10/3 
3 
>>> # to get a floating point number from integer division: 
>>> 10.0/3 
3.3333333333333335 
>>> float(10)/3 
3.3333333333333335 

In Python 3:

>>> 10/3 
3.3333333333333335 
>>> 10//3 
3 

Per ulteriori riferimenti, vedi PEP238.

+13

Io in realtà come questo stile migliore ... mi ricordo in almeno uno di lingua che ho usato (VB?) Il fattore di differenziazione è stato '/' 'vs \' ... ma non riusciva mai a ricordare che era quale! –

+2

Il PEP si occupa anche del fatto che il backslash è riservato ai caratteri di escape o alle nuove linee di escape, in modo tale che il tipo di operatore '' immediatamente eliminato '\ '. –

+0

Grazie, sono stato impegnato con Python 3+ per un po 'di tempo, e non l'ho mai rinnovato, ho sempre fatto 'int (n/i)'. Grandi informazioni qui! – Hidde

122

// è incondizionatamente "divisione pavimenti", per esempio:

>>> 4.0//1.5 
2.0 

Come si vede, anche se entrambi gli operandi sono float s, //ancora piani - in modo da sapere sempre in modo sicuro quello che fara '.

singolo / può o non può pavimento a seconda versione di Python, le importazioni future, e anche le bandiere su cui corsa di Python, per esempio ...:

$ python2.6 -Qold -c 'print 2/3' 
0 
$ python2.6 -Qnew -c 'print 2/3' 
0.666666666667 

Come si vede, unico / possono piano, o può restituire un float, basato su problemi completamente non locali, fino al valore del flag -Q compreso ... ;-).

Quindi, se e quando si sa si desidera pavimenti, sempre uso //, che garantisce. Se e quando sai di avere non vuoi vuoi pavimenti, schiaffi uno float() intorno ad altri operandi e usa /. Qualsiasi altra combinazione, e siete in balia di versione, le importazioni, e bandiere -!)

+8

È interessante notare che il troncamento // restituisce ancora un float – Lucretiel

+0

L'operatore // esegue una divisione floored, non troncante/troncata. –

+0

Questa è la risposta più diretta basata sulla natura di questa domanda, imho. La risposta più votata è utile, ma questo rende più chiaro il motivo per cui sceglieresti uno sull'altro in Python2. –

20

Per completare la risposta di Alex, vorrei aggiungere che a partire da Python 2.2.0a2, from __future__ import division è una comoda alternativa all'utilizzo di un sacco di float(…)/…. Tutte le divisioni eseguono divisioni float, ad eccezione di quelle con //. Funziona con tutte le versioni dalla 2.2.0a2 in poi.

7

// può essere considerato un alias di math.floor() per divisioni con valore di ritorno di tipo float. Funziona come no-op per divisioni con valore di ritorno di tipo int.

import math 
# let's examine `float` returns 
# ------------------------------------- 
# divide 
>>> 1.0/2 
0.5 
# divide and round down 
>>> math.floor(1.0/2) 
0.0 
# divide and round down 
>>> 1.0 // 2 
0.0 

# now let's examine `integer` returns 
# ------------------------------------- 
>>> 1/2 
0 
>>> 1//2 
0 
13

A complemento di queste altre risposte, l'operatore // offre anche notevoli vantaggi (3x) prestazioni rispetto /, presumendo che si desidera divisione intera.

$ python -m timeit '20.5 // 2' 
100000000 loops, best of 3: 0.0149 usec per loop 
$ python -m timeit '20.5/2' 
10000000 loops, best of 3: 0.0484 usec per loop 
$ python -m timeit '20/2' 
10000000 loops, best of 3: 0.043 usec per loop 
$ python -m timeit '20 // 2' 
100000000 loops, best of 3: 0.0144 usec per loop 
Problemi correlati