68 votos

Qué significa el signo de porcentaje en Python

En el tutorial hay un ejemplo para encontrar números primos:

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...     else:
...         # loop fell through without finding a factor
...         print(n, 'is a prime number')
...

Entiendo que el doble == es una prueba de igualdad, pero no entiendo la parte if n % x. Puedo explicar verbalmente cada parte y decir qué hace la declaración para el ejemplo. Pero no entiendo cómo encaja el signo de porcentaje.

¿Qué significa realmente if n % x?

153voto

IfLoop Puntos 59461

El % hace dos cosas, dependiendo de sus argumentos. En este caso, actúa como el operador de módulo, lo que significa que cuando sus argumentos son números, divide el primero por el segundo y devuelve el restante. 34 % 10 == 4 ya que 34 dividido por 10 es tres, con un restante de cuatro.

Si el primer argumento es un string, lo formatea usando el segundo argumento. Esto es un poco complicado, por lo que remitiré a la documentación, pero solo como ejemplo:

>>> "foo %d bar" % 5
'foo 5 bar'

Sin embargo, el comportamiento de formateo de strings se complementa desde Python 3.1 a favor del mecanismo string.format():

Las operaciones de formateo descritas aquí muestran una variedad de peculiaridades que llevan a una serie de errores comunes (como no mostrar correctamente tuplas y diccionarios). Usar la nueva interfaz str.format() ayuda a evitar estos errores, y también proporciona un enfoque generalmente más poderoso, flexible y extensible para formatear texto.

Y afortunadamente, casi todas las nuevas características también están disponibles desde python 2.6 en adelante.

73voto

inkedmn Puntos 12655

Operador de módulo; da el residuo de dividir el valor de la izquierda por el valor de la derecha. Por ejemplo:

3 % 1 sería igual a cero (ya que 3 se divide uniformemente por 1)

3 % 2 sería igual a 1 (ya que dividir 3 por 2 resulta en un residuo de 1).

35voto

MSeifert Puntos 6307

 

¿Qué significa el signo de porcentaje?

Es un operador en Python que puede significar varias cosas dependiendo del contexto. Gran parte de lo que sigue ya fue mencionado (o insinuado) en las otras respuestas, pero pensé que podría ser útil proporcionar un resumen más extenso.

% para Números: Operación de módulo / Resto

El signo de porcentaje es un operador en Python . Se describe como:

 x % y resto de x / y 

Entonces te da el resto / resto que resta si divides x por y. En general (al menos en Python) dado un número x y un divisor y :

 x == y * (x // y) + (x% y) 

Por ejemplo, si divides 5 por 2:

>>> 5 // 2
2
>>> 5% 2
1

>>> 2 * (5 // 2) + (5% 2)
5

Generalmente se usa la operación de módulo para probar si un número divide uniformemente a otro número, eso se debe a que los múltiplos de un número módulo ese número devuelven 0:

>>> 15% 5 # 15 es 3 * 5
0

>>> 81% 9 # 81 es 9 * 9
0

Así es como se usa en tu ejemplo, no puede ser un número primo si es un múltiplo de otro número (excepto por sí mismo y uno), eso es lo que hace esto:

 if n% x == 0:
     break

Si sientes que n% x == 0 no es muy descriptivo, podrías ponerlo en otra función con un nombre más descriptivo:

 def is_multiple (number, divisor):
     return number% divisor == 0

...

Si es_multiple (n, x):
     break

En lugar de is_multiple también podría llamarse evenly_divides o algo similar. Eso es lo que se prueba aquí.

Similar a eso, a menudo se usa para determinar si un número es "impar" o "par":

 def is_odd (number):
     return number% 2 == 1

 def is_even (number):
     return number% 2 == 0

Y en algunos casos también se usa para la indexación de matrices/listas cuando se desea un comportamiento de envoltura (ciclismo), entonces solo tomas módulo el "índice" por la "longitud de la matriz" para lograr eso:

>>> l = [0, 1, 2]
>>> length = len(l)
>>> for index in range(10):
... imprime(l[index% longitud])
0
1
2
0
1
2
0
1
2
0

Tenga en cuenta que también hay una función para este operador en la biblioteca estándar operator.mod (y el alias operator.__mod__ ):

>>> import operator
>>> operator.mod (5, 2) # equivalente a 5% 2
1

Pero también está la asignación aumentada % = que asigna el resultado de nuevo a la variable:

>>> a = 5
>>> a% = 2 # igual a: a = a% 2
>>> a
1

% para cadenas: Formateo de cadenas al estilo de printf

Para cadenas el significado es completamente diferente, allí es una forma (en mi opinión la más limitada y fea) para hacer el formato de cadenas:

>>> "% s is% s." % ("esto", "bueno")
'esto es bueno'

Aquí el % en la cadena representa un marcador seguido de una especificación de formato. En este caso usé % s lo que significa que espera una cadena. Luego, la cadena se sigue de un % que indica que la cadena del lado izquierdo será formateada por el lado derecho. En este caso, el primer % s se reemplaza por el primer argumento esto y el segundo % s se reemplaza por el segundo argumento ( bueno ).

Tenga en cuenta que hay formas mucho mejores (probablemente basadas en opiniones) de formatear cadenas:

>>> "{} es {}.".format("esto", "bueno")
'esto es bueno.'

% en Jupyter/IPython: comandos mágicos

Para citar la documentación :

  

Para los usuarios de Jupyter: los comandos mágicos son específicos y proporcionados por el kernel de IPython. Si los comandos mágicos están disponibles en un kernel es una decisión que toma el desarrollador del kernel caso por caso. Para funcionar correctamente, los magics deben usar un elemento de sintaxis que no sea válido en el lenguaje subyacente. Por ejemplo, el kernel de IPython usa el elemento de sintaxis % para magias ya que % no es un operador unario válido en Python. Mientras que, el elemento de sintaxis tiene significado en otros idiomas.

Esto se usa regularmente en cuadernos Jupyter y similares:

 In [1]: a = 10
          b = 20
          % timeit a + b # un% -> magia de línea

54.6 ns ± 2.7 ns por bucle (promedio ± desviación estándar de 7 ejecuciones, 10000000 bucles cada uno)

En [2]: %% timeit # dos %% -> magia de celda
          a ** b

362 ns ± 8.4 ns por bucle (promedio ± desviación estándar de 7 ejecuciones, 1000000 bucles cada uno)

El operador % en matrices (en el ecosistema NumPy / Pandas)

El operador % sigue siendo el operador de módulo cuando se aplica a estas matrices, pero devuelve una matriz que contiene el resto de cada elemento en la matriz:

>>> import numpy as np
>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

>>> a% 2
array([0, 1, 0, 1, 0, 1, 0, 1, 0, 1])

Personalización del operador % para tus propias clases

Por supuesto, puedes personalizar cómo funcionan tus propias clases cuando se les aplica el operador % . ¡Generalmente deberías usarlo solo para implementar operaciones de módulo! Pero esa es una guía, no una regla estricta.

Solo para proporcionar un ejemplo simple que muestra cómo funciona:

 clase MyNumber (objeto):
     def __init__ (self, valor):
         self.value = valor

     def __mod__ (self, otro):
         print ("__mod__ llamado en '{! r}'".forma (self))
         volver self.value% otro

     def __repr__ (sí mismo):
         return "{self.__class__.__name__} ({self.value! R})".format (self = sí mismo)

Este ejemplo no es realmente útil, simplemente imprime y luego delega el operador al valor almacenado, pero muestra que __mod__ se llama cuando se aplica % a una instancia:

>>> a = MyNumber (10)
>>> a% 2
__mod__ llamado en 'MyNumber (10)'
0

Tenga en cuenta que también funciona para % = sin necesidad de implementar explícitamente __imod__ :

>>> a = MyNumber (10)
>>> a% = 2
__mod__ llamado en 'MyNumber (10)'

>>> a
0

Sin embargo, también podría implementar explícitamente __imod__ para sobrescribir la asignación aumentada:

 clase MyNumber (objeto):
     def __init__ (self, valor):
         self.value = valor

     def __mod__ (self, otro):
         print ("__mod__ llamado en '{! r}'".format (self))
         volver self.value% otro

     def __imod__ (self, otro):
         print ("__imod__ llamado en '{! r}'".format (self))
         self.value% = otro
         volver a

     def __repr__ (sí mismo):
         return "{self.__class__.__name__} ({self.value!r})".format (self = sí mismo)

Ahora % = se sobrescribe explícitamente para funcionar in situ:

>>> a = MyNumber (10)
>>> a% = 2
__imod__ llamado en 'MyNumber (10)'

>>> a
MyNumber (0)

32voto

Stephen Puntos 1921

Aunque esto esté ligeramente fuera de tema, ya que la gente lo encontrará buscando "signo de porcentaje en Python" (como hice yo), quería señalar que el signo % también se usa para prefijar una función "mágica" en iPython: https://ipython.org/ipython-doc/3/interactive/tutorial.html#magic-functions

1voto

Jon W Puntos 7032

En python 2.6 el operador '%' realizaba un módulo. No creo que lo hayan cambiado en 3.0.1

El operador de módulo te dice el resto de una división de dos números.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X