¿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 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)