Qual è il risultato di% in Python?


241

Che cosa significa il %in un calcolo? Non riesco a capire cosa faccia.

Ad esempio, calcola una percentuale del calcolo: 4 % 2è apparentemente uguale a 0. Come?

Risposte:


304

L'operatore% (modulo) restituisce il resto dalla divisione del primo argomento per il secondo. Gli argomenti numerici vengono prima convertiti in un tipo comune. Un argomento zero right solleva l'eccezione ZeroDivisionError. Gli argomenti possono essere numeri in virgola mobile, ad es. 3,14% 0,7 è uguale a 0,34 (poiché 3,14 è uguale a 4 * 0,7 + 0,34.) L'operatore modulo restituisce sempre un risultato con lo stesso segno del secondo operando (o zero); il valore assoluto del risultato è strettamente inferiore al valore assoluto del secondo operando [2].

Tratto da http://docs.python.org/reference/expressions.html

Esempio 1: 6%2 valuta 0perché non c'è resto se 6 è diviso per 2 (3 volte).

Esempio 2 : 7%2valuta 1perché c'è un resto di 1quando 7 è diviso per 2 (3 volte).

Quindi, per riassumere, restituisce il resto di un'operazione di divisione o 0se non c'è resto. Quindi 6%2significa trovare il resto di 6 diviso per 2.


7
Perché tutti gli esempi hanno un numero più grande sulla destra? Qualcuno può spiegare il risultato del 2% 6 che produce 2?
Wookie,

8
Il primo numero è il numeratore e il secondo è il denominatore. Nel tuo esempio 2 diviso 6 è 0 resto 2, quindi il risultato è 2.
David

4
Aggiorna la tua risposta, di seguito troverai risposte più precise. In C / C ++ % è per 'rem' mentre in Python% è per 'mod'. ad esempio - 21 % 4è 3 in Python.
Azam,

Puoi spiegare perché -11%5 = 4??
dahiya_boy,

@dahiya_boy Ho aggiunto la spiegazione di GvR alla mia risposta meno votata di seguito.
Paulo Scardine,

143

Un po 'fuori tema, %viene anche usato nelle operazioni di formattazione delle stringhe come %=sostituire i valori in una stringa:

>>> x = 'abc_%(key)s_'
>>> x %= {'key':'value'}
>>> x 
'abc_value_'

Ancora una volta, fuori tema, ma sembra essere una piccola funzionalità documentata che mi ha richiesto un po 'di tempo per rintracciare, e ho pensato che fosse correlato al calcolo del modulo Pythons per il quale questa pagina SO si classifica molto bene.


Esiste una logica su% utilizzata anche come riferimento per la formattazione delle stringhe o è solo un incidente della storia che quel simbolo è stato sovraccaricato? Questa dovrebbe essere una sua domanda?
WAF,

5
Scarsamente documentato? Non credo: String Formatting Operations
KurzedMetal,

@KurzedMetal - %=non appare in quella pagina
P. Myer Nore il

@WAF L' %operatore è stato scelto perché rispecchia gli specificatori di percentuale utilizzati all'interno della stringa stessa.
MI Wright,

@ P.MyerNore So che è quasi 3 anni dopo, ma può aiutare gli altri. Leggi il primo paragrafo evidenziato nel secondo. 5.6.2 collegata sopra da KurzedMetal. "X% = {}" è semplicemente una forma abbreviata di "x = x% {...}"
Sujay Phadke

58

Un'espressione simile x % yrestituisce il resto di x ÷ y- beh, tecnicamente si tratta di "modulo" invece di "promemoria", quindi i risultati possono essere diversi se si sta confrontando con altre lingue in cui si %trova l'operatore residuo. Ci sono alcune sottili differenze (se sei interessato alle conseguenze pratiche, vedi anche "Perché Python's Integer Division Floors" qui sotto).

La precedenza è la stessa degli operatori /(divisione) e *(moltiplicazione).

>>> 9 / 2
4
>>> 9 % 2
1
  • 9 diviso 2 è uguale a 4.
  • 4 volte 2 è 8
  • 9 meno 8 è 1 - il resto.

Python gotcha : a seconda della versione di Python che stai utilizzando, %è anche l'operatore (deprecato) di interpolazione di stringhe, quindi fai attenzione se provieni da una lingua con cast di tipo automatico (come PHP o JS) in cui un'espressione simile '12' % 2 + 3è legale: in Python si tradurrà in quello TypeError: not all arguments converted during string formattingche probabilmente sarà abbastanza confuso per te.

[aggiornamento per Python 3]

Commenti utente n00p:

9/2 è 4.5 in python. Devi fare una divisione intera in questo modo: 9 // 2 se vuoi che Python ti dica quanti oggetti interi rimangono dopo la divisione (4).

Per essere precisi, in Python 2 la divisione intera era l'impostazione predefinita (attenzione, questa risposta è più antica di mio ragazzo che è già a scuola e al tempo 2.x era mainstream):

$ python2.7
Python 2.7.10 (default, Oct  6 2017, 22:29:07)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 9 / 2
4
>>> 9 // 2
4
>>> 9 % 2
1

Nei moderni 9 / 2risultati di Python 4.5infatti:

$ python3.6
Python 3.6.1 (default, Apr 27 2017, 00:15:59)
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 9 / 2
4.5
>>> 9 // 2
4
>>> 9 % 2
1

[aggiornare]

L'utente dahiya_boy ha chiesto nella sessione di commento:

Q. Puoi spiegare perché -11 % 5 = 4- dahiya_boy

Questo è strano, vero? Se provi questo in JavaScript:

> -11 % 5
-1

Questo perché in JavaScript %è l'operatore "resto", mentre in Python è l'operatore "modulo" (clock math).

Puoi ottenere la spiegazione direttamente da GvR :


Modifica - dahiya_boy

In Java e iOS -11 % 5 = -1mentre in pitone e rubino -11 % 5 = 4.

Ben metà del motivo è spiegato da Paulo Scardine , e il resto della spiegazione è qui sotto

In Java e iOS, %il resto indica che se dividi l' 11% 5Quotient = 2 and remainder = 1e -11% 5Quotient = -2 and remainder = -1.

Codice di esempio in iOS rapido.

inserisci qui la descrizione dell'immagine

Ma quando parliamo in Python, esso dà il modulo dell'orologio. E funziona con la formula seguente

mod(a,n) = a - {n * Floor(a/n)}

Questo significa,

mod(11,5) = 11 - {5 * Floor(11/5)} => 11 - {5 * 2}

Così, mod(11,5) = 1

E

mod(-11,5) = -11 - 5 * Floor(11/5) => -11 - {5 * (-3)}

Così, mod(-11,5) = 4

Codice di esempio in Python 3.0.

inserisci qui la descrizione dell'immagine


Perché Python's Integer Division Floors

Oggi mi è stato chiesto (di nuovo) di spiegare perché la divisione intera in Python restituisce il pavimento del risultato invece di troncare verso zero come C.

Per i numeri positivi, non c'è sorpresa:

>>> 5//2
2

Ma se uno degli operandi è negativo, il risultato viene pavimentato, ovvero arrotondato da zero (verso l'infinito negativo):

>>> -5//2
-3
>>> 5//-2
-3

Questo disturba alcune persone, ma c'è una buona ragione matematica. L'operazione di divisione di interi (//) e il suo fratello, l'operazione di modulo (%), vanno insieme e soddisfano una bella relazione matematica (tutte le variabili sono numeri interi):

a/b = q with remainder r

tale che

b*q + r = a and 0 <= r < b

(supponendo che aeb siano> = 0).

Se vuoi che la relazione si estenda per il negativo a (mantenendo b positivo), hai due possibilità: se troncerai q verso zero, r diventerà negativo, in modo che l'invariante cambi in 0 <= abs (r) <altrimenti, tu può pavimentare q verso l'infinito negativo e l'invariante rimane 0 <= r <b. [aggiornamento: risolto questo paragrafo]

Nella teoria dei numeri matematica, i matematici preferiscono sempre quest'ultima scelta (vedi ad esempio Wikipedia ). Per Python, ho fatto la stessa scelta perché ci sono alcune interessanti applicazioni dell'operazione modulo in cui il segno di a non è interessante. Prendi in considerazione la possibilità di prendere un timestamp POSIX (secondi dall'inizio del 1970) e di trasformarlo nell'ora del giorno. Dato che ci sono 24 * 3600 = 86400 secondi in un giorno, questo calcolo è semplicemente t% 86400. Ma se dovessimo esprimere i tempi prima del 1970 usando numeri negativi, la regola "troncare verso zero" darebbe un risultato insignificante! Usando la regola del pavimento tutto funziona bene.

Altre applicazioni a cui ho pensato sono i calcoli delle posizioni dei pixel nella computer grafica. Sono sicuro che ce ne sono altri.

Per negativo b, comunque, tutto gira e l'invariante diventa:

0 >= r > b.

Quindi perché C non lo fa in questo modo? Probabilmente l'hardware non lo ha fatto al momento della progettazione di C. E l'hardware probabilmente non l'ha fatto in questo modo perché nell'hardware più vecchio, i numeri negativi erano rappresentati come "segno + magnitudine" piuttosto che la rappresentazione del complemento a due usata in questi giorni (almeno per gli interi). Il mio primo computer era un mainframe Control Data e utilizzava il proprio complemento per numeri interi e float. Un modello di 60 indicava zero negativo!

Tim Peters, che sa dove sono sepolti tutti gli scheletri in virgola mobile di Python, ha espresso qualche preoccupazione per il mio desiderio di estendere queste regole al modulo in virgola mobile. Probabilmente ha ragione; la regola di troncamento verso verso l'infinito può causare una perdita di precisione per x% 1.0 quando x è un numero negativo molto piccolo. Ma non è abbastanza per me rompere il modulo intero, e // è strettamente associato a quello.

PS. Nota che sto usando // invece di / - questa è la sintassi di Python 3, e ho anche permesso in Python 2 di sottolineare che sai che stai invocando la divisione di numeri interi. L'operatore / in Python 2 è ambiguo, poiché restituisce un risultato diverso per due operandi interi rispetto a un int e un float o due float. Ma questa è una storia totalmente separata; vedi PEP 238.

Postato da Guido van Rossum alle 9:49


1
Inoltre, help(divmod)documenta l'invariante q, r = divmod(x y) <==> q*y + r == x.
Chepner,

49

Il modulo è un'operazione matematica, a volte descritta come "aritmetica dell'orologio". Trovo che descriverlo come un semplice resto sia fuorviante e confuso perché maschera la vera ragione per cui viene usato così tanto nell'informatica. È davvero usato per avvolgere i cicli.

Pensa a un orologio: supponi di guardare un orologio in tempo "militare", dove l'intervallo di tempo va dalle 0:00 alle 23,59. Ora se vuoi che succeda qualcosa ogni giorno a mezzanotte, vorresti che l'ora attuale mod 24 fosse zero:

if (ora% 24 == 0):

Puoi pensare a tutte le ore della storia che si avvolgono attorno a un cerchio di 24 ore più e più volte e l'ora corrente del giorno è quel numero infinitamente lungo mod 24. È un concetto molto più profondo di un semplice resto, è un modo matematico gestire i cicli ed è molto importante nell'informatica. Viene inoltre utilizzato per avvolgere le matrici, consentendo di aumentare l'indice e utilizzare il modulo per tornare all'inizio dopo aver raggiunto la fine dell'array.


1
Ecco come viene implementato in Python:a % b = a - b * floor(a/b)
Aiman ​​Al-Eryani,


7

Nella maggior parte delle lingue% viene utilizzato per il modulo . Python non fa eccezione.


11
Per quanto posso vedere, Python è insolito in quanto usa% per modulo; Fortran, C / C ++ e Java usano% per indicare il resto. (Vedi stackoverflow.com/questions/13683563/… , le differenze sono nel modo in cui vengono gestiti i valori negativi e frazionari.) Le lingue che fanno una distinzione (ad esempio Ada, Haskell e Scheme) usano le parole "rem" e "mod" (o "resto" e "modulo") anziché%.
Jim Pivarski,

5
Aggiornamento: ho trovato questa grande tabella di operazioni modulo / resto per lingua en.wikipedia.org/wiki/Modulo_operation . Python è insolito ma non unico (per esempio, TCL e Lua condividono la convenzione di Python.)
Jim Pivarski,

5

L'operatore% Modulo può essere utilizzato anche per la stampa di stringhe (proprio come in C) come definito su Google https://developers.google.com/edu/python/strings .

      # % operator
  text = "%d little pigs come out or I'll %s and %s and %s" % (3, 'huff', 'puff', 'blow down')

Questo sembra un po 'fuori tema ma sicuramente aiuterà qualcuno.


4

x % ycalcola il resto della divisione xdiviso per ydove il quoziente è un numero intero . Il resto ha il segno di y.


Su Python 3 il calcolo produce 6.75; questo perché /fa una vera divisione, non una divisione intera come (di default) su Python 2. Su Python 2 1 / 4dà 0, poiché il risultato viene arrotondato per difetto .

La divisione intera può essere eseguita anche su Python 3, con l' //operatore, quindi per ottenere il 7 come risultato, è possibile eseguire:

3 + 2 + 1 - 5 + 4 % 2 - 1 // 4 + 6

Inoltre, puoi ottenere la divisione dello stile Python su Python 2, semplicemente aggiungendo la linea

from __future__ import division

come prima riga di codice sorgente in ciascun file sorgente.


8
Ricorda che i bambini #sono per i commenti ed //è un operatore.
Mike Causer,

3

Operatore modulo, viene utilizzato per la divisione del resto su numeri interi, in genere, ma in Python può essere utilizzato per numeri in virgola mobile.

http://docs.python.org/reference/expressions.html

L'operatore% (modulo) restituisce il resto dalla divisione del primo argomento per il secondo. Gli argomenti numerici vengono prima convertiti in un tipo comune. Un argomento zero right solleva l'eccezione ZeroDivisionError. Gli argomenti possono essere numeri in virgola mobile, ad es. 3,14% 0,7 è uguale a 0,34 (poiché 3,14 è uguale a 4 * 0,7 + 0,34.) L'operatore modulo restituisce sempre un risultato con lo stesso segno del secondo operando (o zero); il valore assoluto del risultato è strettamente inferiore al valore assoluto del secondo operando [2].


3

È un'operazione modulo, tranne quando è un vecchio operatore di formattazione di stringhe in stile C, non un'operazione modulo . Vedi qui per i dettagli. Vedrai molto di questo nel codice esistente.


3

Inoltre, esiste un'utile funzione integrata chiamata divmod:

divmod (a, b)

Prendi due numeri (non complessi) come argomenti e restituisce una coppia di numeri costituiti dal loro quoziente e resto quando si usa la divisione lunga.


2

Fai attenzione a

(3 +2 + 1 - 5) + (4 % 2) - (1/4) + 6

anche con le parentesi risulta 6,75 anziché 7 se calcolato in Python 3.4.


E anche l'operatore '/' non è così facile da capire (python2.7): prova ...

- 1/4

1 - 1/4

Questo è un po 'fuori tema qui, ma dovrebbe essere considerato quando si valuta l'espressione sopra :)


2
Come sarebbe mai stato 7? Semplifica a (1)+(0)-(0.25)+(6).
J.Steve,

1

È stato difficile per me trovare prontamente casi d'uso specifici per l'uso di% online, ad esempio perché la divisione frazionaria del modulo o la divisione negativa del modulo danno la risposta. Spero che questo aiuti a chiarire domande come questa:

Divisione dei moduli in generale:

La divisione del modulo restituisce il resto di un'operazione di divisione matematica. Lo fa come segue:

Supponiamo che abbiamo un dividendo di 5 e un divisore di 2, la seguente operazione di divisione sarebbe (equivalente a x):

dividend = 5
divisor = 2

x = 5/2 
  1. Il primo passo nel calcolo del modulo è condurre la divisione di interi:

    x_int = 5 // 2 (la divisione intera in python usa una doppia barra)

    x_int = 2

  2. Successivamente, l'output di x_int viene moltiplicato per il divisore:

    x_mult = x_int * divisore x_mult = 4

  3. Infine, il dividendo viene sottratto da x_mult

    dividendo - x_mult = 1

  4. L'operazione del modulo, quindi, restituisce 1:

    5% 2 = 1

Applicazione per applicare il modulo a una frazione

Example: 2 % 5 

Il calcolo del modulo quando applicato a una frazione è lo stesso di sopra; tuttavia, è importante notare che la divisione intera comporterà un valore pari a zero quando il divisore è maggiore del dividendo:

dividend = 2 
divisor = 5

La divisione intera risulta in 0 mentre il; pertanto, quando viene eseguito il passaggio 3 sopra, il valore del dividendo viene trasferito (sottratto da zero):

dividend - 0 = 2  —> 2 % 5 = 2 

Applicazione per applicare il modulo a un negativo

Si verifica la divisione del pavimento in cui il valore della divisione intera viene arrotondato per difetto al valore intero più basso:

import math 

x = -1.1
math.floor(-1.1) = -2 

y = 1.1
math.floor = 1

Pertanto, quando si esegue la divisione di interi, è possibile ottenere un risultato diverso da quello previsto!

L'applicazione dei passaggi sopra riportati sul seguente dividendo e divisore illustra il concetto di modulo:

dividend: -5 
divisor: 2 

Passaggio 1: applicare la divisione dei numeri interi

x_int = -5 // 2  = -3

Passaggio 2: moltiplicare il risultato della divisione intera per il divisore

x_mult = x_int * 2 = -6

Passaggio 3: sottrarre il dividendo dalla variabile moltiplicata, notare il doppio negativo.

dividend - x_mult = -5 -(-6) = 1

Perciò:

-5 % 2 = 1

0

L'operatore% (modulo) restituisce il resto dalla divisione del primo argomento per il secondo. Gli argomenti numerici vengono prima convertiti in un tipo comune.

3 + 2 + 1 - 5 + 4% 2 - 1/4 + 6 = 7

Questo si basa sulla precedenza dell'operatore.


0

%è modulo . 3 % 2 = 1,4 % 2 = 0

/ è (un numero intero in questo caso) divisione, quindi:

3 + 2 + 1 - 5 + 4 % 2 - 1 / 4 + 6
1 + 4%2 - 1/4 + 6
1 + 0 - 0 + 6
7



0

Modulo: divide l'operando della mano sinistra per l'operando della mano destra e restituisce il resto.

Se aiuta:

1:0> 2%6
=> 2
2:0> 8%6
=> 2
3:0> 2%6 == 8%6
=> true

... e così via.


0

Ho scoperto che il modo più semplice per cogliere l'operatore modulo (%) è attraverso una lunga divisione. È il resto e può essere utile per determinare un numero pari o dispari:

4%2 = 0

  2
2|4
 -4
  0


11%3 = 2

  3
3|11
 -9
  2

dà il resto di una divisione non molto da prendere in considerazione
DeafaltCoder
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.