Что означает знак процента в Python


В учебнике есть пример нахождения простых чисел:

>>> 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')
...
Я понимаю, что двойное == - это тест на равенство, но я не понимаю часть if n % x. Например, я могу вербально пройти через каждую часть и сказать, что утверждение делает для примера. Но я не понимаю, как сюда попадает знак процента.

Что на самом деле говорит if n % x?

8 40

8 ответов:

Оператор модуля; дает остаток левого значения, деленного на правое значение. Например:

3 % 1 равно нулю (так как 3 делится равномерно на 1)

3 % 2 будет равно 1 (так как деление 3 на 2 приводит к остатку от 1).

% делает две вещи, в зависимости от своих аргументов. В этом случае он действует как оператор по модулю, то есть, когда его аргументы являются числами, он делит первое на второе и возвращает остаток . Так как 34 делится на 10 - это три, а остаток равен четырем.

Если первый аргумент является строкой, он форматирует ее с помощью второго аргумента. Это немного связано, поэтому я буду ссылаться на документацию , но только в качестве примера:

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

Однако, поведение форматирования строки дополняется с Python 3.1 в пользу строки .format() механизм:

Операции форматирования, описанные здесь, демонстрируют различные причуды, которые приводят к ряду распространенных ошибок (таких как неправильное отображение кортежей и словарей). Использование более новых str.format() интерфейс помогает избежать этих ошибок, а также обеспечивает в целом более мощный, гибкий и расширяемый подход к форматированию текст.

И, к счастью, почти все новые функции также доступны начиная с python 2.6.

Хотя это немного не по теме, так как люди найдут это, ища "процентный знак в Python" (как и я), я хотел бы отметить, что знак % также используется для префикса "волшебной" функции в iPython: https://ipython.org/ipython-doc/3/interactive/tutorial.html#magic-functions

Что означает знак процента?

Это оператор в 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

И в некоторых случаях он также используется для индексирования массива / списка, когда требуется поведение обтекания (циклического), тогда вы просто умножаете "индекс" на "длину массива", чтобы достичь этого:

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

% для строк: printf-стиль Форматирование Строк

Для строк смысл совершенно другой, там это один способ (на мой взгляд самый ограниченный и уродливый) для выполнения форматирования строки:

>>> "%s is %s." % ("this", "good") 
'this is good'

Здесь % в строке представляет собой заполнитель, за которым следует спецификация форматирования. В этом случае я использовал %s, что означает, что он ожидает строку. Затем за строкой следует %, который указывает, что строка с левой стороны будет отформатирована правой со стороны руки. В этом случае первый %s заменяется первым аргументом this, а второй %s - вторым аргументом (good).

Обратите внимание, что есть гораздо лучшие (вероятно, основанные на мнении) способы форматирования строк:

>>> "{} is {}.".format("this", "good")
'this is good.'

% в Jupyter / IPython: магические команды

Процитируем docs :

Для пользователей Jupyter: магия специфична и обеспечивается ядром IPython. Доступна ли магия на ядре - это вопрос. решение, которое принимается разработчиком ядра на основе каждого ядра. Чтобы правильно работать, магия должна использовать синтаксический элемент, который не является допустимым в базовом языке. Например, ядро IPython использует синтаксический элемент % для magics, поскольку % не является допустимым унарным оператором в 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 / Экосистема панд)

Оператор % остается оператором по модулю, когда применяется к этим массивам, но он возвращает массив, содержащий остаток каждого элемента в массиве:

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

В python 2.6 оператор " % " выполняет модуль. Я не думаю, что они изменили его в 3.0.1

Оператор по модулю сообщает вам остаток от деления двух чисел.

Он проверяет, является ли модуль деления. Например, в случае, когда вы перебираете все числа от 2 до n и проверяете, делится ли n на любое из чисел между ними. Проще говоря, вы проверяете, является ли данное число n простым. (Подсказка: вы можете проверить до n / 2).

Оператор модуля. Остаток при делении на два числа.

Например:

>>> 5 % 2 = 1 # remainder of 5 divided by 2 is 1
>>> 7 % 3 = 1 # remainer of 7 divided by 3 is 1
>>> 3 % 1 = 0 # because 1 divides evenly into 3

Blockquote x % n = = 0 это означает, что x/n и значение напоминания будут взяты в результате и сравниваться с нулем....

Пример: 4/5= = 0

4/5 напоминание равно 1

1==0 (ложь)