Qual é o resultado de% no Python?

241

O que faz %em um cálculo? Parece que não consigo descobrir o que faz.

Calcula uma porcentagem do cálculo, por exemplo: 4 % 2é aparentemente igual a 0. Como?

laranja
fonte

Respostas:

304

O operador% (módulo) produz o restante da divisão do primeiro argumento pelo segundo. Os argumentos numéricos são primeiro convertidos em um tipo comum. Um argumento zero right gera a exceção ZeroDivisionError. Os argumentos podem ser números de ponto flutuante, por exemplo, 3,14% 0,7 é igual a 0,34 (uma vez que 3,14 é igual a 4 * 0,7 + 0,34). O operador módulo sempre produz um resultado com o mesmo sinal que seu segundo operando (ou zero); o valor absoluto do resultado é estritamente menor que o valor absoluto do segundo operando [2].

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

Exemplo 1: 6%2 avalia como 0porque não há resto se 6 é dividido por 2 (3 vezes).

Exemplo 2 : 7%2avalia como 1porque existe um restante de 1quando 7 é dividido por 2 (3 vezes).

Então, para resumir isso, ele retorna o restante de uma operação de divisão, ou 0se não houver restante. Então, 6%2significa encontrar o restante de 6 dividido por 2.

meder omuraliev
fonte
7
Por que todos os exemplos têm um número maior à direita? Alguém pode explicar o resultado de 2% 6, que produz 2?
Wookie 27/03
8
O primeiro número é o numerador e o segundo é o denominador. No seu exemplo 2 dividido por 6 é 0 restante 2, portanto, o resultado é 2
David
4
Atualize sua resposta, há respostas mais precisas abaixo. Em C / C ++ % é para 'rem', enquanto em Python% é para 'mod'. por exemplo, - 21 % 4é 3 em Python.
Azam
Você pode, por favor, explicar o porquê -11%5 = 4?
Dahiya_boy 17/07/19
@dahiya_boy Adicionei a explicação do GvR à minha resposta menos votada abaixo.
Paulo Scardine 17/07/19
143

Um pouco fora do tópico, %também é usado em operações de formatação de cadeias, como %=para substituir valores em uma cadeia:

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

Novamente, fora do tópico, mas parece ser um pequeno recurso documentado que me levou um pouco para rastrear, e eu pensei que estava relacionado ao cálculo do módulo Pythons para o qual esta página SO é altamente classificada.

mrmagooey
fonte
Existe alguma lógica para% também ser usada como referência de formatação de string ou é apenas um acidente histórico que esse símbolo tenha sido sobrecarregado? Essa deveria ser sua própria pergunta?
WAF
5
Mal documentado? Acho que não: Operações de formatação de
strings
@KurzedMetal - %=não aparece nessa página
P. Myer Nore
@WAF O %operador foi escolhido porque reflete os especificadores de porcentagem usados ​​na própria string.
MI Wright
@ P.MyerNore Eu sei que isso é quase 3 anos depois, mas pode ajudar os outros. Leia o primeiro parágrafo destacado no segundo. 5.6.2 vinculado acima pelo KurzedMetal. O "x% = {}" é simplesmente um formato abreviado para "x = x% {...}"
Sujay Phadke
58

Uma expressão como é x % yavaliada para o restante de x ÷ y- bem, tecnicamente é "módulo" em vez de "lembrete", portanto os resultados podem ser diferentes se você estiver comparando com outros idiomas em que %está o operador restante. Existem algumas diferenças sutis (se você estiver interessado nas consequências práticas, consulte também "Por que a divisão inteira do Python flutua" abaixo).

Precedência é o mesmo que operadores /(divisão) e *(multiplicação).

>>> 9 / 2
4
>>> 9 % 2
1
  • 9 dividido por 2 é igual a 4.
  • 4 vezes 2 é 8
  • 9 menos 8 é 1 - o restante.

Python gotcha : dependendo da versão do Python que você está usando, %também é o operador de interpolação de string (descontinuado); portanto, observe se você vem de uma linguagem com conversão automática de tipo (como PHP ou JS) em que uma expressão como '12' % 2 + 3é legal: in Python, resultará em TypeError: not all arguments converted during string formattingque provavelmente será bastante confuso para você.

[atualização para Python 3]

Comentários do usuário n00p:

9/2 é 4,5 em python. Você precisa fazer a divisão inteira da seguinte maneira: 9 // 2 se quiser que o python diga quantos objetos inteiros restam após a divisão (4).

Para ser mais preciso, a divisão inteira costumava ser o padrão no Python 2 (lembre-se, essa resposta é mais antiga que o meu garoto que já está na escola e na época 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

Nos 9 / 2resultados modernos do Python, de 4.5fato:

$ 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

[atualizar]

O usuário dahiya_boy perguntou na sessão de comentários:

P. Você pode explicar por que -11 % 5 = 4- dahiya_boy

Isso é estranho, certo? Se você tentar isso em JavaScript:

> -11 % 5
-1

Isso ocorre porque no JavaScript %é o operador "restante", enquanto no Python é o operador "módulo" (matemática do relógio).

Você pode obter a explicação diretamente do GvR :


Editar - dahiya_boy

Em Java e iOS, -11 % 5 = -1enquanto em python e ruby -11 % 5 = 4.

Bem, metade da razão é explicada por Paulo Scardine , e o restante da explicação está abaixo aqui

Em Java e iOS, %dá o restante Isso significa que se você dividir 11% 5Quotient = 2 and remainder = 1e -11% 5Quotient = -2 and remainder = -1.

Exemplo de código no iOS rápido.

insira a descrição da imagem aqui

Mas quando falamos em python, dá o módulo de clock. E seu trabalho com a fórmula abaixo

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

Isso significa,

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

Assim, mod(11,5) = 1

E

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

Assim, mod(-11,5) = 4

Código de exemplo no python 3.0.

insira a descrição da imagem aqui


Por que a divisão de número inteiro do Python flutua

Hoje me pediram (novamente) para explicar por que a divisão inteira em Python retorna o piso do resultado em vez de truncar para zero como C.

Para números positivos, não há surpresa:

>>> 5//2
2

Mas se um dos operandos for negativo, o resultado será calculado, ou seja, arredondado para longe de zero (em direção ao infinito negativo):

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

Isso incomoda algumas pessoas, mas há uma boa razão matemática. A operação de divisão inteira (//) e seu irmão, a operação de módulo (%), caminham juntos e satisfazem um bom relacionamento matemático (todas as variáveis ​​são inteiras):

a/b = q with remainder r

de tal modo que

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

(supondo que aeb sejam> = 0).

Se você deseja que o relacionamento se estenda para a negativo (mantendo-se b positivo), você tem duas opções: se você truncar q em direção a zero, r se tornará negativo, de modo que a invariante mude para 0 <= abs (r) <caso contrário, você pode andar q em direção ao infinito negativo, e a invariante permanece 0 <= r <b. [atualização: corrigido este parágrafo]

Na teoria matemática dos números, os matemáticos sempre preferem a última opção (veja, por exemplo, a Wikipedia ). Para Python, fiz a mesma escolha, porque existem algumas aplicações interessantes da operação do módulo em que o sinal de a é desinteressante. Considere pegar um carimbo de data / hora do POSIX (segundos desde o início de 1970) e transformá-lo na hora do dia. Como há 24 * 3600 = 86400 segundos em um dia, esse cálculo é simplesmente t% 86400. Mas se expressássemos tempos antes de 1970 usando números negativos, a regra "truncar para zero" daria um resultado sem sentido! Usando a regra do piso, tudo funciona bem.

Outras aplicações em que pensei são cálculos de posições de pixels em computação gráfica. Tenho certeza que existem mais.

Para b negativo, a propósito, tudo apenas muda, e o invariante se torna:

0 >= r > b.

Então, por que C não faz dessa maneira? Provavelmente o hardware não fez isso no momento em que o C foi projetado. E o hardware provavelmente não fez dessa maneira, porque no hardware mais antigo, os números negativos foram representados como "sinal + magnitude" em vez da representação de complemento dos dois usada atualmente (pelo menos para números inteiros). Meu primeiro computador foi um mainframe de dados de controle e usou o complemento de um para números inteiros e flutuadores. Um padrão de 60 significava zero negativo!

Tim Peters, que sabe onde estão enterrados todos os esqueletos de ponto flutuante do Python, expressou alguma preocupação com meu desejo de estender essas regras ao módulo de ponto flutuante. Ele provavelmente está certo; a regra truncar para o infinito negativo pode causar perda de precisão para x% 1,0 quando x é um número negativo muito pequeno. Mas isso não é suficiente para eu quebrar o módulo inteiro, e // está fortemente associado a isso.

PS. Observe que estou usando // em vez de / - essa é a sintaxe do Python 3 e também é permitido no Python 2 enfatizar que você sabe que está invocando uma divisão inteira. O operador / no Python 2 é ambíguo, pois retorna um resultado diferente para dois operandos inteiros do que para um int e um float ou dois floats. Mas essa é uma história totalmente separada; ver PEP 238.

Postado por Guido van Rossum às 09:49

Paulo Scardine
fonte
1
Além disso, help(divmod)documenta o invariante q, r = divmod(x y) <==> q*y + r == x.
chepner
49

O módulo é uma operação matemática, algumas vezes descrita como "aritmética do relógio". Acho que descrevê-lo simplesmente como um restante é enganoso e confuso, porque oculta a verdadeira razão pela qual é usado tanto na ciência da computação. É realmente usado para envolver ciclos.

Pense em um relógio: suponha que você observe um relógio em horário "militar", onde o intervalo de horários varia de 0:00 a 23,59. Agora, se você deseja que algo aconteça todos os dias à meia-noite, você deseja que o mod 24 da hora atual seja zero:

if (hora% 24 == 0):

Você pode pensar em todas as horas da história envolvendo um círculo de 24 horas sem parar e a hora atual do dia é esse número infinitamente longo, mod 24. É um conceito muito mais profundo do que apenas um restante, é uma maneira matemática lidar com ciclos e é muito importante na ciência da computação. Também é usado para agrupar em torno de matrizes, permitindo aumentar o índice e usar o módulo para voltar ao início depois de atingir o final da matriz.

jarvis01123
fonte
1
É assim que é implementado no Python:a % b = a - b * floor(a/b)
Aiman ​​Al-Eryani
7

Na maioria dos idiomas,% é usado para o módulo . Python não é exceção.

sorpigal
fonte
11
Tanto quanto posso ver, o Python é incomum, pois usa% para o módulo; Fortran, C / C ++ e Java usam% para significar o restante. (Consulte stackoverflow.com/questions/13683563/… , as diferenças estão em como os valores fracionários e negativos são tratados.) Os idiomas que fazem uma distinção (por exemplo, Ada, Haskell e Scheme) usam as palavras "rem" e "mod" (ou "restante" e "módulo") em vez de%.
Jim Pivarski
5
Atualização: Encontrei esta excelente tabela de operações de módulo / restante por idioma en.wikipedia.org/wiki/Modulo_operation . Python é incomum, mas não exclusivo (por exemplo, TCL e Lua share convenção do Python.)
Jim Pivarski
5

O operador% Modulo também pode ser usado para imprimir strings (como em C), conforme definido no 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')

Isso parece um pouco fora do tópico, mas certamente ajudará alguém.

Harshit Chaudhary
fonte
4

x % ycalcula o restante da divisão xdividido por yonde o quociente é um número inteiro . O restante tem o sinal de y.


No Python 3, o cálculo rende 6.75; isso ocorre porque existe /uma divisão verdadeira, e não uma divisão inteira como (por padrão) no Python 2. No Python 2 1 / 4, o 0 é 0, pois o resultado é arredondado para baixo.

A divisão inteira também pode ser feita no Python 3, com //operador, para obter o 7 como resultado, você pode executar:

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

Além disso, você pode obter a divisão de estilo Python no Python 2, apenas adicionando a linha

from __future__ import division

como a primeira linha do código fonte em cada arquivo fonte.

Antti Haapala
fonte
8
Lembre-se de crianças #é para comentários e //é um operador.
Mike Causer
3

Operador de módulo, é usado para divisão restante em números inteiros, normalmente, mas em Python pode ser usado para números de ponto flutuante.

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

O operador% (módulo) produz o restante da divisão do primeiro argumento pelo segundo. Os argumentos numéricos são primeiro convertidos em um tipo comum. Um argumento zero right gera a exceção ZeroDivisionError. Os argumentos podem ser números de ponto flutuante, por exemplo, 3,14% 0,7 é igual a 0,34 (uma vez que 3,14 é igual a 4 * 0,7 + 0,34). O operador módulo sempre produz um resultado com o mesmo sinal que seu segundo operando (ou zero); o valor absoluto do resultado é estritamente menor que o valor absoluto do segundo operando [2].

wkl
fonte
3

É uma operação de módulo, exceto quando é um operador de formatação de string no estilo C à moda antiga, não uma operação de módulo . Veja aqui para detalhes. Você verá muito disso no código existente.

John Machin
fonte
3

Além disso, existe uma função interna útil chamada divmod:

divmod (a, b)

Tome dois números (não complexos) como argumentos e retorne um par de números que consiste em seu quociente e restante ao usar a divisão longa.

warvariuc
fonte
2

Esteja ciente que

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

mesmo com os colchetes, resulta em 6,75 em vez de 7, se calculado no Python 3.4.


E o operador '/' também não é fácil de entender (python2.7): tente ...

- 1/4

1 - 1/4

Isso é um pouco fora de tópico aqui, mas deve ser considerado ao avaliar a expressão acima :)

Bernhard
fonte
2
Como isso seria 7? Simplifica para (1)+(0)-(0.25)+(6).
J.Steve
1

Foi difícil para mim encontrar prontamente casos de uso específicos para o uso de% online, por exemplo, por que fazer divisão de módulo fracionário ou divisão de módulo negativo resulta na resposta que ele faz. Espero que isso ajude a esclarecer perguntas como esta:

Divisão de módulos em geral:

A divisão de módulo retorna o restante de uma operação de divisão matemática. É o seguinte:

Digamos que temos um dividendo de 5 e um divisor de 2, a seguinte operação de divisão seria (igual a x):

dividend = 5
divisor = 2

x = 5/2 
  1. A primeira etapa no cálculo do módulo é conduzir a divisão inteira:

    x_int = 5 // 2 (a divisão inteira em python usa barra dupla)

    x_int = 2

  2. Em seguida, a saída de x_int é multiplicada pelo divisor:

    x_mult = x_int * divisor x_mult = 4

  3. Por fim, o dividendo é subtraído do x_mult

    dividendo - x_mult = 1

  4. A operação do módulo, portanto, retorna 1:

    5% 2 = 1

Aplicação para aplicar o módulo a uma fração

Example: 2 % 5 

O cálculo do módulo quando aplicado a uma fração é o mesmo que acima; no entanto, é importante observar que a divisão inteira resultará em um valor zero quando o divisor for maior que o dividendo:

dividend = 2 
divisor = 5

A divisão inteira resulta em 0 enquanto que; portanto, quando a etapa 3 acima é executada, o valor do dividendo é realizado (subtraído de zero):

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

Aplicação para aplicar o módulo a um valor negativo

A divisão de piso ocorre na qual o valor da divisão inteira é arredondado para o menor valor inteiro:

import math 

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

y = 1.1
math.floor = 1

Portanto, quando você faz uma divisão inteira, pode obter um resultado diferente do esperado!

A aplicação das etapas acima no seguinte dividendo e divisor ilustra o conceito de módulo:

dividend: -5 
divisor: 2 

Etapa 1: aplicar divisão inteira

x_int = -5 // 2  = -3

Etapa 2: Multiplique o resultado da divisão inteira pelo divisor

x_mult = x_int * 2 = -6

Etapa 3: Subtraia o dividendo da variável multiplicada, observe o duplo negativo.

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

Portanto:

-5 % 2 = 1
N.Atanasov
fonte
0

O operador% (módulo) produz o restante da divisão do primeiro argumento pelo segundo. Os argumentos numéricos são primeiro convertidos em um tipo comum.

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

Isso é baseado na precedência do operador.

user225312
fonte
0

%é módulo . 3 % 2 = 1,4 % 2 = 0

/ é (um número inteiro neste caso) divisão, então:

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

Módulo - Divide o operando esquerdo pelo operando direito e retorna o restante.

Se ajudar:

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

... e assim por diante.

gr8scott06
fonte
0

Descobri que a maneira mais fácil de entender o operador do módulo (%) é através de uma divisão longa. É o restante e pode ser útil para determinar um número que seja par ou ímpar:

4%2 = 0

  2
2|4
 -4
  0


11%3 = 2

  3
3|11
 -9
  2
JJJ
fonte
dá o resto de uma divisão não há muito a tomar
DeafaltCoder