Что означает знак процента?
Это оператор в Python, который может означать несколько вещей в зависимости от контекста. Многое из того, что следует, уже упоминалось (или намекалось) в других ответах, но я подумал, что было бы полезно предоставить более обширное резюме.
%
для номеров: операция по модулю / остаток / остаток
Знак процента - это оператор в Python . Это описывается как:
x % y remainder of x / y
Таким образом, вы получите остаток / остаток, который останется , если вы «разделите пол» 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
И в некоторых случаях он также используется для индексации массивов / списков, когда требуется поведение циклического (циклического) циклического изменения, тогда вы просто модулируете "index" на "length массива", чтобы достичь этого:
>>> 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: Магия специфична для ядра 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)