73

在本教程中有一个查找素数的示例:

>>> 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说了什么?

4

8 回答 8

152

% 做了两件事,具体取决于它的论点。在这种情况下,它充当模运算符,这意味着当它的参数是数字时,它将第一个除以第二个并返回余数34 % 10 == 4因为 34 除以 10 是三,余数是四。

如果第一个参数是字符串,则使用第二个参数对其进行格式化。这有点涉及,所以我将参考文档,但仅作为示例:

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

但是,从Python 3.1开始对字符串格式化行为进行了补充,以支持字符串.format()机制:

此处描述的格式化操作表现出各种怪癖,这些怪癖会导致许多常见错误(例如无法正确显示元组和字典)。使用更新的str.format()界面有助于避免这些错误,并且还提供了一种通常更强大、更灵活和可扩展的文本格式设置方法。

值得庆幸的是,几乎所有的新功能都可以从 python 2.6 开始使用。

于 2009-06-07T06:58:52.793 回答
75

模算子;给出左值除以右值的余数. 像:

3 % 1将等于 0(因为 3 除以 1)

3 % 2将等于 1(因为 3 除以 2 的余数为 1)。

于 2009-06-07T06:50:49.953 回答
34

虽然这有点离题,因为人们会通过搜索“Python 中的百分比符号”(就像我所做的那样)来找到它,我想指出,% 符号也用于在 iPython 中作为“魔术”函数的前缀:https ://ipython.org/ipython-doc/3/interactive/tutorial.html#magic-functions

于 2017-04-25T04:56:54.743 回答
34

百分号是什么意思?

它是 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-style 字符串格式

对于字符串,含义完全不同,有一种方法(在我看来是最有限和最丑陋的)进行字符串格式化:

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

这里%字符串中的 代表一个占位符,后跟一个格式规范。在这种情况下,我使用%s了这意味着它需要一个字符串。然后字符串后面跟着a %,表示左侧的字符串将被右侧格式化。在这种情况下,第一个%s被第一个参数替换,this第二个%s被第二个参数替换(good)。

请注意,格式化字符串有更好的(可能是基于意见的)方法:

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

%在 Jupyter/IPython 中:魔术命令

引用文档

致 Jupyter 用户:魔术是 IPython 内核特有的并由其提供。内核是否可以使用魔法是内核开发人员基于每个内核做出的决定。为了正常工作,Magics 必须使用在底层语言中无效的语法元素。例如,IPython 内核使用%魔法的语法元素,因为%它不是 Python 中有效的一元运算符。而语法元素在其他语言中具有意义。

这经常用于 Jupyter notebooks 和类似的:

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)
于 2018-07-07T10:27:07.183 回答
1

在 python 2.6 中,'%' 运算符执行模数。我不认为他们在 3.0.1 中改变了它

模运算符告诉您两个数字相除的余数。

于 2009-06-07T06:49:41.610 回答
1

它检查除法的模数。例如,如果您正在迭代从 2 到 n 的所有数字,并检查 n 是否可以被两者之间的任何数字整除。简而言之,您正在检查给定数字 n 是否为素数。(提示:您最多可以检查 n/2)。

于 2009-06-07T06:50:55.540 回答
1

模运算符。两个数相除的余数。

例如:

>>> 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
于 2011-11-06T13:03:08.980 回答
0

x % n == 0
这意味着 x/n 和提醒的值将作为结果并与零比较....

例如:4/5==0

4/5 提醒是 4

4==0(错误)

于 2018-07-06T17:42:48.030 回答