Что означает знак процента в 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?


person Lonnie Price    schedule 07.06.2009    source источник


Ответы (8)


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

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

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

person brettkelly    schedule 07.06.2009
comment
К вашему сведению, это называется Евклидово деление. - person A. Gille; 12.02.2018
comment
Рискуя быть педантичным, я подумал, что должен уточнить, что модуль (%) не совпадает с остатком для отрицательных чисел. Остаток от -2 / 3 будет -2, но -2 % 3 = 1 - person Riker; 16.11.2018
comment
@A.Gille, чтобы уточнить, хотя это результат евклидова деления, разница здесь в том, что оператор модуля возвращает только остаток, а не возвращает частное. - person K Paul; 17.12.2020

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

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

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

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

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

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

person SingleNegationElimination    schedule 07.06.2009
comment
Я считаю, что оператор форматирования строк был удален в Python 3. - person David Z; 07.06.2009
comment
@David: это просто устарело. - person SilentGhost; 07.06.2009
comment
Я тоже так думал, но не нашел, когда огляделся. Второй взгляд все понял. Объясняет редактирование. - person SingleNegationElimination; 08.06.2009
comment
В документах говорится: оператор % дополняется более мощным методом форматирования строк, format(). Я не думаю, что это означает удаление/устарел. - person Leftium; 23.01.2011
comment
@Leftium документы. На python.org/3/whatsnew/ указано, что % будет объявлено устаревшим в python 3.1 и «удалено из языка позднее». Однако эта страница довольно старая. Я не могу найти упоминания об этом в документах python 3.2 или 3.3. Я надеюсь, что разработчики передумали и решили оставить % как есть. format() хорош и мощен, но % намного удобнее для основных целей. - person TM.; 30.01.2013
comment
Отличная беседа, ребята. Спасибо! Является ли это использование % в качестве строкового оператора уникальным для Python? - person Charles; 04.03.2021

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

person Stephen    schedule 25.04.2017

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

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

% для строк: printfстиль форматирования строк

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

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

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

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

person Jon W    schedule 07.06.2009

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

person laginimaineb    schedule 07.06.2009

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

Например:

>>> 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
person Community    schedule 06.11.2011

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

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

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

4==0 (ложь)

person Hemant    schedule 06.07.2018