Что означает знак процента?
Это оператор в Python, который может означать несколько вещей в зависимости от контекста. Многое из того, что следует, уже упоминалось (или намекалось) в других ответах, но я подумал, что было бы полезно предоставить более подробное резюме.
%
для чисел: операция по модулю / остаток / отдых
Знак процента — это оператор в Python. Это описано как:
x % y remainder of x / y
Таким образом, он дает вам остаток, который остается, если вы разделить" х на у. Обычно (по крайней мере, в Python) с учетом числа x
и делителя y
:
x == y * (x // y) + (x % y)
Например, если вы разделите 5 на 2:
>>> 5 // 2
2
>>> 5 % 2
1
>>> 2 * (5 // 2) + (5 % 2)
5
В общем, вы используете операцию по модулю, чтобы проверить, делится ли число на другое число без остатка, потому что кратное число по модулю этого числа возвращает 0:
>>> 15 % 5 # 15 is 3 * 5
0
>>> 81 % 9 # 81 is 9 * 9
0
Вот как он используется в вашем примере, он не может быть простым, если он кратен другому числу (кроме самого себя и единицы), вот что это делает:
if n % x == 0:
break
Если вы чувствуете, что n % x == 0
не очень описателен, вы можете поместить его в другую функцию с более описательным именем:
def is_multiple(number, divisor):
return number % divisor == 0
...
if is_multiple(n, x):
break
Вместо is_multiple
его также можно назвать evenly_divides
или что-то подобное. Вот что здесь проверяется.
Подобно этому, он часто используется, чтобы определить, является ли число «нечетным» или «четным»:
def is_odd(number):
return number % 2 == 1
def is_even(number):
return number % 2 == 0
И в некоторых случаях он также используется для индексации массива/списка, когда требуется циклическое поведение, тогда вы просто модулируете «индекс» на «длину массива», чтобы добиться этого:
>>> l = [0, 1, 2]
>>> length = len(l)
>>> for index in range(10):
... print(l[index % length])
0
1
2
0
1
2
0
1
2
0
Обратите внимание, что в стандартной библиотеке operator.mod
также есть функция для этого оператора. (и псевдоним operator.__mod__
):
>>> import operator
>>> operator.mod(5, 2) # equivalent to 5 % 2
1
Но есть также расширенное присваивание %=
, которое присваивает результат обратно переменной:
>>> a = 5
>>> a %= 2 # identical to: a = a % 2
>>> a
1
Для строк смысл совсем другой, там есть один способ (на мой взгляд, самый ограниченный и уродливый) форматирования строк:
>>> "%s is %s." % ("this", "good")
'this is good'
Здесь %
в строке представляет собой заполнитель, за которым следует спецификация форматирования. В этом случае я использовал %s
, что означает, что он ожидает строку. Затем за строкой следует %
, который указывает, что строка в левой части будет отформатирована в правой части. В этом случае первый %s
заменяется первым аргументом this
, а второй %s
заменяется вторым аргументом (good
).
Обратите внимание, что есть гораздо лучшие (возможно, основанные на мнении) способы форматирования строк:
>>> "{} is {}.".format("this", "good")
'this is good.'
%
в Jupyter/IPython: волшебные команды
Чтобы процитировать документы:
Для пользователей Jupyter: Magics специфичны для ядра IPython и предоставляются им. Доступность магии в ядре — это решение, которое принимается разработчиком ядра отдельно для каждого ядра. Для правильной работы Magics должен использовать элемент синтаксиса, недопустимый в базовом языке. Например, ядро IPython использует синтаксический элемент %
для магии, поскольку %
не является допустимым унарным оператором в Python. В то время как элемент синтаксиса имеет значение на других языках.
Это регулярно используется в ноутбуках Jupyter и подобных:
In [1]: a = 10
b = 20
%timeit a + b # one % -> line-magic
54.6 ns ± 2.7 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [2]: %%timeit # two %% -> cell magic
a ** b
362 ns ± 8.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Оператор %
для массивов (в экосистеме NumPy/Pandas)
Оператор %
по-прежнему является оператором по модулю при применении к этим массивам, но он возвращает массив, содержащий остаток от каждого элемента в массиве:
>>> 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])
Настройка оператора %
для ваших собственных классов
Конечно, вы можете настроить работу ваших собственных классов, когда к ним применяется оператор %
. Как правило, вы должны использовать его только для реализации операций по модулю! Но это рекомендация, а не жесткое правило.
Просто приведу простой пример, показывающий, как это работает:
class MyNumber(object):
def __init__(self, value):
self.value = value
def __mod__(self, other):
print("__mod__ called on '{!r}'".format(self))
return self.value % other
def __repr__(self):
return "{self.__class__.__name__}({self.value!r})".format(self=self)
Этот пример не очень полезен, он просто печатает, а затем делегирует оператору сохраненное значение, но он показывает, что __mod__
вызывается, когда %
применяется к экземпляру:
>>> a = MyNumber(10)
>>> a % 2
__mod__ called on 'MyNumber(10)'
0
Обратите внимание, что это также работает для %=
без явной необходимости реализации __imod__
:
>>> a = MyNumber(10)
>>> a %= 2
__mod__ called on 'MyNumber(10)'
>>> a
0
Однако вы также можете явно реализовать __imod__
, чтобы перезаписать расширенное назначение:
class MyNumber(object):
def __init__(self, value):
self.value = value
def __mod__(self, other):
print("__mod__ called on '{!r}'".format(self))
return self.value % other
def __imod__(self, other):
print("__imod__ called on '{!r}'".format(self))
self.value %= other
return self
def __repr__(self):
return "{self.__class__.__name__}({self.value!r})".format(self=self)
Теперь %=
явно перезаписывается для работы на месте:
>>> a = MyNumber(10)
>>> a %= 2
__imod__ called on 'MyNumber(10)'
>>> a
MyNumber(0)
person
MSeifert
schedule
07.07.2018